1.继承的本质——复用
1.1继承的定义
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保 持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。
class A{
int a;
};
class B:public A{
int b;
};
1.2继承的定义格式
下面我们看到Base是父类,也称作基类。Derive是子类,也称作派生类。
1.3继承方式和访问限定符
对于基类中不同访问属性的成员,在不同的继承方式下派生类对其的访问属性也不同。
具体不同方式继承后访问属性如下,可以结合理解记忆。
总结特性:
1.继承方式可以省略但最好写,class的继承默认继承方式为private,struct默认继承方式为public。
2.从上不同方式继承后访问属性表格可以总结出以下规律,访问属性:public > protected > private,继承后的访问属性取基类中访问属性与继承方式中较小的那一个。
2.继承中的赋值兼容转换
C++中派生类对象可以赋值给基类的对象/指针/引用(指针、引用会指向派生类中属于基类的那一部分) ,但是基类对象不能赋值给派生类。
class Base {
int b;
};
class Derive : public Base {
int d;
};
int main()
{
Base b;
Base& b1 = b;
Base* b2;
Derive d;
b = d;
b1 = d;
*b2 = d;
return 0;
}
3.继承中的作用域
C++中有各种各样的域,他们对变量的生命周期和编译时函数名变量名的查找有影响,如下
那么在继承中基类和派生类的域中有什么注意事项呢
一、基类和派生类有其独立作用域,基类和派生类可以有同名成员,若有同名成员优先访问当前域。子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏(重定义)。(在子类成员函数中,可以使用 基类::基类成员 显示访问)
二、隐藏只要函数名相同,不用参数相同。
三、实践中最好不要重定义。
4.继承中的默认构造、默认拷贝构造、默认析构
●子类生成的默认构造:
父类成员——调用其无参构造
子类自己的内置成员——一般不处理
子类自己的自定义成员——调用其无参构造
●子类生成的默认拷贝构造:
父类成员——调用其拷贝构造
子类自己的内置成员——一般不处理
子类自己的自定义成员——调用其拷贝构造
●子类生成的默认析构:
父类成员——调用其析构
子类自己的内置成员——一般不处理
子类自己的自定义成员——调用其析构
5.继承中析构函数的处理
编译器会自动调用父类析构函数。因为子类析构时可能会用到父类成员,构造函数可以保证先父后子,可以显式调用父类构造(初始化列表)。析构函数不能保证先子后父,故父类析构函数不用用户自己调用,编译器会自动调用。
6.友元、静态成员
一、友元关系不能继承
二、基类定义了静态成员,则继承体系中只有其一个同名变量
三、只有非静态成员函数才能定义为虚函数
7.多继承中虚继承的引入和继承中的构造函数调用顺序
7.1虚继承
多继承即继承两个及以上的基类,然而多继承有时会出现一些问题看如下类图和代码
class Base {
string id;
};
class Base1 : public Base {
};
class Base2 : public Base {
};
class Derive:public Base1,public Base2{
};
此时会出现数据冗余和二义性的问题。
此时若要访问Base中的成员具有二义性,必须指定类域才能精准访问,为解决这个问题引入了虚基类 \虚继承,如下
class Base {
string id;
};
class Base1 :virtual public Base {
};
class Base2 :virtual public Base {
};
class Derive:public Base1,public Base2{
};
当经过这样的的继承后该派生类只继承该基类一次(只保留第一次继承)。
7.2构造函数调用顺序
若同一层次中同时包含虚基类和非虚基类其中构造函数调用顺序为1.虚基类构造函数、2.非虚基类构造函数、3.自己的成员变量。(析构函数调用顺序与构造函数相反)
8.继承的总结
一、继承与组合本质都是复用
二、当继承和组合都可以使用时看适不适合优先使用组合,继承是一种is a的关系,组合是一种has a的关系
三、继承这种通过生成派生类的复用,通常被称为白箱复用(white-box reuse)(从外部可见)。
四、组合要求被组合对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse)(从外部不可见)。
五、实践中尽量多用组合。组合的耦合度低代码维护性好。