Constructor, destructors and inheritance
和别的对象类似,导出类的对象也能够用构造函数初始化。当调用构造函数时候,从基类继承过来的数据成员也必须初始化。这个通过调用基类的构造函数实现。而导出类对象中剩下的部分则通过调用导出类特定的构造函数初始化。继续用前面person, employee, programmer类做例子。
class Person{
public:
Person(){};
Person(const string& n):name(n){};
string name;
};
上例中定义了两个构造函数,一个是默认构造函数,另外一个是包含了人名的构造函数。声明如下对象时:
Person p("David");
则第二个构造函数被调用。
对Employee类,也可定义如下构造函数:
class Employee : public Person{
public:
Employee(): salary(0) {};
Employee(const string&n,long int s):Person(n),salary(s){};
long int salary;
};
第二个构造函数中,用初始化列表初始化了对象不同部分。person(n)是调用基类的构造函数。如有以下声明:
Employee e1("Lisa",20000);
因为上例中参数n的值是Lisa,因此初始化列表中有表达式Person(“Lisa”)。因此类person中第二个构造函数被调用,其结果是数据成员name被初始化为Lisa.然后数据成员salary被初始化为20000.
注意:基类的构造函数总是在导出类的数据成员被初始化之前调用,并且也在括号里面的语句被执行前调用。
当然,基类的默认构造函数被调用的前提是该构造函数存在。如果基类没有默认的构造函数,则导出类的构造函数的初始化列表中的基类的一个构造函数必须被调用,否则出错。例如,假设类person的默认构造函数不存在。则必须重新写类employee的第一个构造函数:
Employee():Person(""),salary(0) {};
如果一个类没有定义构造函数,默认构造函数被自动定义。我们可以断然无误的说没有自己构造函数的基类将自动产生一个默认的构造函数。
如果没有给一个导出类定义自己的构造函数,也将有一个默认的构造函数产生。看以下例子:
class Athlete:public Person{
.....
private:
bool elite;
};
注意我们没有定义任何构造函数。此时我们将得到一个自动的默认构造函数,可以想像此构造函数如下:
Athlete():Person(){} //automatically generated
基类的默认构造函数也会被调用。
现在可以声明类Athlete的变量:
Athlete at;
类person的默认构造函数将被调用,数据成员name将被初始化,然后数据成员elite没有被初始化。
当定义一个类,通常会有一个自动产生的拷贝构造函数和自动产生的assignment operator(=). 此点对导出类也适用。
如果有更进一步的继承关系,构造函数的调用可以扩展到不同level.看下例:
class Programmer : public Employee{
public:
Programmer(){}
Programmer(const string& n, long int s,const string& f):Employee(n,s),fav(f){}
....
string fav;
};
此时,基类employee有两个参数的构造函数被首先调用,这构造函数将首先调用他基类person的构造函数。这导致person首先被初始化,接下来是类employee,最后是初始化类programmer.在C++中,初始化必须遵循一种严格的顺序。最高阶的基类首先被初始化,然后依次向下,直到最后导出的类成员被初始化。
总结:
B是D的直接基类,D是B的导出类:
1) 在D的构造函数的初始化列表中,基类的构造函数被首先调用:
D::D(parameters):B(parameters),…{statements}
如果这情况没有发生,B的默认构造函数被自动调用。
2)如果D有自动产生的默认构造函数,则基类默认构造函数被首先在其中调用。
3)构造函数中初始化顺序:
基类构造函数;
类数据成员被初始化(根据类定义中声明的顺序)
括号{}内语句被执行。
destructors比较简单。destructors不会被继承。通常只有在相应的constructor分配的内存的情况下且内存必须被释放时候才调用destructors.和constructor相比,destructor类似,但执行顺序相反。即最后导出类的destructor被最先执行。