前面分析过继承,继承使得子类可以继承父类的属性和方法,但是构造和析构除外。
为什么构造和析构不能被继承
首先我们要清除,构造函数的职责是用来初始化类的对象的,构造函数在类的对象之前执行,而继承是子类的调用父类的属性和方法,父类的对象都没创建你怎么去调用,因此构造析构不能被继承。
拷贝构造函数和拷贝赋值操作符会不会被继承?之前也分析过,在执行拷贝构造函数和拷贝赋值操作符之前需要调用构造函数来初始化类的对象的。想一想连对象都没有,你怎么在子类中调用父类的属性和方法。
调用原理
1、子类对象在创建时会首先调用父类的构造函数
2、父类构造函数执行结束后,执行子类的构造函数
3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用
4、析构函数调用的先后顺序与构造函数相反
类型兼容性原则
是指在需要父类对象的地方,可以用公有派生类(子类)对象来代替。因为公有派生类(子类)可以继承除构造和析构之外的所有成员,这样公有派生类(子类)就具备了父类的所有功能,凡是父类可以解决的问题,公有派生类(子类)都可以解决。
兼容规则中所指的替代包括以下情况:
1.子类对象可以当做父类对象使用
2.子类对象可以直接赋值给父类对象
3.子类对象可以直接初始化父类对象
4.父类指针可以直接指向子类对象
5.父类引用可以直接引用子类对象
class Parent
{
public:
Parent(){cout<<"父类构造函数"<<endl;}
Parent(const Parent &obj){cout<<"父类赋值构造函数"<<endl;}
~Parent(){cout<<"父类析构函数"<<endl;}
void Print1(){cout<<"我是父类"<<endl;}
};
class Child:public Parent
{
public:
Child(){cout<<"子类构造函数"<<endl;}
Child(const Child&obj){cout<<"子类赋值构造函数"<<endl;}
~Child(){cout<<"子类析构函数"<<endl;}
void Print2(){cout<<"我是子类"<<endl;}
};
void HowToPrint1(Parent *base)
{
base->Print1();
}
void HowToPrint2(Parent &base)
{
base.Print1();
}
//main
{
Parent p;
p.Print1();
Child c;
c.Print1();
c.Print2();
//基类指针(引用)指向 子类对象
Parent *base = NULL;
base = &c;
base->Print1();
//指针做函数参数
HowToPrint1(&p);
HowToPrint1(&c);
//引用做函数参数
HowToPrint2(p);
HowToPrint2(c);
//父类对象初 始换 子类对象
Parent p1 = c;//调用赋值构造函数
p1.Print1();
}
执行结果: