一、继承的概念
继承是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有的类的特性的基础上进行一个扩展,可以增加其功能。
二、继承的定义格式
三、继承关系与访问限定符
总结:
1、公有继承基类的成员,全部是基类的成员。
2、保护和私有继承基类的成员都变成各自的继承。
3、基类的私有成员无法继承。
4、使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public。
5、在类外只能访问公有成员,私有成员和保护成员都不可访问。
6、所有的继承方式,在派生类的内部都可以访问基类的公有成员和保护成员,私有成员在子类中不可见。
7、类与类之间的关系有三种:
has-a:一个类的成员是另一个类的对象,
is-a,父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。
uses-a:一个类的成员函数的参数是另外一个类的对象。-
四、派生类的默认成员函数
和类一样,派生类的默认成员函数也有六个:构造函数,拷贝构造函数,析构函数,赋值操作符重载,取地址操作符重载,consr修饰的取地址操作符重载
五、继承体系中的作用域
1、基类和派生类是两个不同的作用域。
2、如果基类和派生类有同名成员,派生类的成员将屏蔽基类对成员的直接访问。(在派生类的成员函数中,可以使用基类::基类成员来访问)
3、最好不要定义同名成员
六、赋值兼容规则
1、子类对象可以赋值给父类对象
2、父类对象不能赋值给子类对象
3、父类的指针/引用可以指向子类对象
4、子类的指针/引用不能指向父类对象(可以通过强制类型转化)
七、多重继承
1、多重继承:一个派生类有两个或两个以上的直接基类。
2、声明多重继承的方式
如果已经声明了类A类B,此时可以声明多重继承的派生类C。
class C: public A ,public B
{类C的成员函数};
八、菱形继承
1、菱形继承的模型
C1,C2 是D的派生类,B是C1,C2的派生类。
此时会出现一个问题,类B保存了两份类D的成员, 导致了一个数据 冗余和浪费空间的问题,同时会产生了一个二义性的问题。对此,我们引入了虚继承。
(菱形继承的对象模型)
2、虚继承
(1)虚继承的格式
声明如下:class 派生类名:virtual 继承方式 基类名
(2)虚继承对象模型
(3)虚继承的代码
#include <iostream>
using namespace std;
class D
{
public:
int _d;
};
class C1 :virtual public D
{
public:
int _c1;
};
class C2 :virtual public D
{
public:
int _c2;
};
class B:public C1, public C2
{
public:
int _b;
};
int main()
{
B b;
b._d = 1;
b._c1 = 2;
b._c2 = 3;
b._d = 4;
cout << sizeof(B) << endl;//结果为24(4+8+8+4)
return 0;
}
注意:当将虚拟继承写为B虚拟继承C1,C2时,无法解决二义性的问题。