第五周 继承
1.继承和派生的基本概念
2.继承关系和复合关系
3.覆盖和保护成员
4.派生类的构造函数
5.公有(public)继承的赋值兼容原则
4.派生类的构造函数
class Bug {
private :
int nLegs; int nColor;
public:
int nType;
Bug ( int legs, int color);
void PrintBug (){ };
};
class FlyBug: public Bug // FlyBug 是Bug 的派生类
{
int nWings;
public:
FlyBug( int legs,int color, int wings);
};
Bug::Bug( int legs, int color)//也可以是初始化列表的方式
{
nLegs = legs;
nColor = color;
}
// 错误的FlyBug 构造函数
FlyBug::FlyBug ( int legs,int color, int wings)
{
nLegs = legs; // error,不能访问私有成员
nColor = color; // error,不能访问私有成员
nType = 1; // ok,共有成员
nWings = wings;
}
// 正确的FlyBug 构造函数:初始化列表
FlyBug::FlyBug ( int legs, int color, int wings):Bug( legs, color)
{
nWings = wings;
}
int main() {
FlyBug fb ( 2,3,4);
fb.PrintBug();
fb.nType = 1;
fb.nLegs = 2 ; // error. nLegs is private
return 0;
}
派生类的构造函数
在创建派生类的对象时,需要调用基类的构造函数:初始化派生类对象中从基类继承的成员。在执行一个派生类的构造函数之前,总是先执行基类的构造函数。
调用基类构造函数的两种方式
– 显式方式:在派生类的构造函数中,为基类的构造函数提供参数。
derived::derived(arg_derived-list):base(arg_base-list)
– 隐式方式:在派生类的构造函数中,省略基类构造函数时,派生类的构造函数则自动调用基类的默认构造函数。
派生类的析构函数
派生类的析构函数被执行时,执行完派生类的析构函数后,自动调用基类的析构函数。先构造的后析构。
顺序:基类构造函数-派生类构造函数-派生类析构函数-基类析构函数。
例子:
class Base {
public:
int n;
Base(int i):n(i)
{ cout << "Base " << n << " constructed" << endl;}
~Base()
{ cout << "Base " << n << " destructed" << endl; }
};
class Derived:public Base {
public:
Derived(int i):Base(i)//必须是这种显式
{ cout << "Derived constructed" << endl; }
~Derived()
{ cout << "Derived destructed" << endl;}
};
int main() { Derived Obj(3); return 0; }
输出结果:
Base 3 constructed
Derived constructed
Derived destructed
Base 3 destructed
包含成员对象的派生类的构造函数写法(即派生类是封闭类)
class Bug {
private :
int nLegs; int nColor;
public:
int nType;
Bug ( int legs, int color);
void PrintBug (){ };
};
class Skill {
public:
Skill(int n) { }
};
class FlyBug: public Bug {
int nWings;
Skill sk1, sk2;
public:
FlyBug( int legs, int color, int wings);
};
//封闭类的基类和成员对象都需要初始化
FlyBug::FlyBug( int legs, int color, int wings):Bug(legs,color),sk1(5),sk2(color) ,nWings(wings) {}
封闭派生类对象的构造函数的执行顺序(当然就是上面初始化列表的顺序)
在创建派生类的对象时:
1 ) 先执行基类的构造函数,用以初始化派生类对象中从基类继承的成员;
2) 再执行成员对象类的构造函数,用以初始化派生类对象中成员对象;
3) 最后执行派生类自己的构造函数。
封闭派生类对象消亡时析构函数的执行顺序
在派生类对象消亡时:
1 ) 先执行派生类自己的析构函数
2) 再依次执行各成员对象类的析构函数
3) 最后执行基类的析构函数
析构函数的调用顺序与构造函数的调用顺序相反。