所在的位置: C++ >> C++介绍 >> 813C和C

813C和C

好的面试官不会要求你用自己不懂的语言来编写代码。一般来说,如果面试官要求你用C++写代码,那么,应该是你在简历上提及了C++。要是没能记住所有API,也不用担心,大部分面试官(虽不是全部)并不会那么在意这一点。不过,我们仍建议你学会基本的C++语法,这样才能轻松应对这些问题。

类和继承

虽然C++的类与其他语言的类有些特征相似,不过,还是有必要回顾一下相关部分语法。

下面的代码演示了怎样利用继承实现一个基本的类。

在C++中,所有数据成员和方法均默认为私有(private),可用关键字public修改其属性。

构造函数和析构函数

对象创建时,会自动调用类的构造函数。如果没有定义构造函数,编译器会自动生成一个默认构造函数(DefaultConstructor)。另外,我们也可以定义自己的构造函数。

Person(inta){

id=a;}

这个类的数据成员也可以这样初始化:1Person(inta):id(a){2……3}

在真正的对象创建之前,且在构造函数余下部分代码调用前,数据成员id就会被赋值。在常量数据成员赋值时(只能赋一次值),这种写法特别适用。

析构函数会在对象删除时执行清理工作。对象销毁时,会自动调用析构函数。我们不会显式调用析构函数,因此它不能带参数。

~Person(){

deleteobj;//释放之前这个类里分配的内存}

虚函数

在前面的例子中,我们将p定义为Student类型指针变量:

Student*p=newStudent();

p-aboutMe();

像下面这样,把p定义为Person*又会怎么样?

这么改的话,执行时会打印“Iamaperson”。这是因为函数aboutMe是在编译期决定的,也即所谓的静态绑定(staticbinding)机制。

若要确保调用的是Student的aboutMe函数实现,可以将Person类的aboutMe定义为virtual:

当我们无法(或不想)实现父类的某个方法时,虚函数也能派上用场。例如,设想一下,我们想让Student和Teacher继承自Person,以便实现一个共同的方法,如addCourse(strings)。不过,对Person调用addCourse方法没有多大意义,因为要看对象到底是Student还是Teacher,才能确定该调用哪个方法的具体实现。

在这种情况下,我们可能想将Person类的addCourse定义为虚函数,至于函数实现则留给子类。

注意,将addCourse定义为纯虚函数,Person就成了一个抽象类,不能实例化。

虚析构函数

有了虚函数,很自然地就会出现虚析构函数的概念。假设我们想要实现Person和Student的析构函数。不假思索的话,可能会写出类似如下的代码:

跟之前的例子一样,由于指针p指向Person,对象销毁时自然会调用Person类的析构函数。这样就会有问题,因为Student对象的内存可能得不到释放。

要解决这个问题,只需将Person的析构函数定义为虚析构函数。

编译执行上面的代码,打印输出如下:

Deletingastudent.Deletingaperson.

默认值

如下所示,函数可以指定默认值。注意,所有默认参数必须放在函数声明的右边,因为没有其他途径来指定参数是怎么排列的。

操作符重载

有了操作符重载(operatoroverloading),原本不支持+等操作符的对象,就可以用上这些操作符。举个例子,要想把两个书架(BookShelf)并作一个,我们可以这样重载+操作符:

BookShelfBookShelf::operator+(BookShelfother){...}

指针和引用

指针存放有变量的地址,可直接作用于变量的所有操作,都可以作用在指针上,比如访问和修改变量。

两个指针可以彼此相等,修改其中一个指针指向的值,另一个指针指向的值也会随之改变。实际上,这两个指针指向同一地址。

注意,指针的大小随计算机的体系结构不同而不同:在32位机器上为32位,在64位机器上为64位。请谨记这一点区别,面试官常常会要求求职者准确地回答,某个数据结构到底要占用多少空间。

引用

引用是既有对象的另一个名字(别名),引用本身并不占用内存。例如:

在上面第2行代码中,b是a的引用;修改b,a也随之改变。

创建引用时,必须指定引用指向的内存位置。当然,也可以创建一个独立的引用,如下所示:

/*分配内存,储存12,

*声明指向这块内存的引用b*/

intb=12;

跟指针不同,引用不能为空,也不能重新赋值,指向另一块内存。

指针算术运算

我们经常会看到开发人员对指针执行加法操作,示例如下:

执行p++会跳过sizeof(int)个字节,因此上面的代码会输出1。如果p换作其他类型,p++就会跳过一定数目(等于该数据结构的大小)的字节。

模板

模板是一种代码重用方式,不同的数据类型可以套用同一个类的代码。比如说,我们可能有列表类的数据结构,希望可以放进不同类型的数据。下面的代码通过ShiftedList类实现这一需求。

template

classShiftedList{

T*array;

intoffset,size;

public:

ShiftedList(intsz):offset(0),size(sz){

array=new

T[size];

}

~ShiftedList(){

delete[]array;1

}

voidshiftBy(intn){

offset=(offset+n)%size;

}

TgetAt(inti){

returnarray[convertIndex(i)];

}

void

setAt(Titem,inti){

array[convertIndex(i)]=item;

}

private:

intconvertIndex(inti){

intindex=(i-offset)%size;

while(index0)index+=size;

returnindex;}

};

intmain(){

intsize=4;

ShiftedList*list=new

ShiftedList(size);

for(inti=0;isize;i++){

list-

setAt(i,i);

}

coutlist-getAt(0)endl;

cout

list-getAt(1)endl;

list-shiftBy(1);

coutlist-

getAt(0)endl;

coutlist-getAt(1)endl;

delete

list;

}




转载请注明:http://www.aierlanlan.com/rzfs/7273.html