Chapter 05 : Composition & Inheritance¶
约 826 个字 65 行代码 4 张图片 预计阅读时间 5 分钟
Composition¶
组合(Composition):从已存在的对象中构造新的对象,即复用已有的实现
- 包含(Inclusion)方式:
- 完全(Fully)包含
- 构造函数和析构函数会被自动调用
- 引用(Reference)包含
- 需要手动初始化和销毁对象
- 完全(Fully)包含
- 嵌入对象(Embedded Objects):
- 所有的嵌入对象都必须被初始化
- 当不提供参数时,默认的构造函数(或者自己创建的构造函数)就会被调用
- 构造函数可以用初始化列表
- 可以给子构造函数传递参数
- 析构函数会被自动调用
- 所有的嵌入对象都必须被初始化
Inheritance¶
继承(Inheritance):从已存在的类中克隆新的类并扩展
- 定义一个基类(Base class,或称为超类),用于定义共同属性
- 定义多个派生类(Derived Class,或称为子类),用于继承基类的属性,并添加自己的属性
- 派生类通过
:
指定基类,例如class Derived : public/protected/private Base
- 默认为
private
- 默认为
Scopes and Access¶
- 对于继承类型的不同,访问权限也不同:
关键词 | 在同一个类中 | 在派生类中 | 在类外 |
---|---|---|---|
private | Yes | No | No |
protected | Yes | Yes | No |
public | Yes | Yes | Yes |
class
默认为private
,struct
默认为public
Example
但是如果我们在 foo()
中添加一句 data *= 2
,则会报错:
但是如果我们将 data
从 private
改为 protected
,则又可以正常运行了
C++ 在访问保护当中还有令一种关键词为 friend
,可以让一个函数或者类访问另一个类的私有成员
- 由类本身来控制访问权限
friend
可以是:- 一个函数
- 一个成员函数或者其他类
- 甚至是整个类
Tips
事实上,private 并非真正的无法访问,它只是对类来说无法访问而非对象
我们事实上可以通过指针来变相地绕过 private 来访问成员(这需要我们通过猜测类的地址来获取)
cx 说这就是破解软件的原理,但不鼓励我们去做这玩意,因为没前途因为都慢慢开始开源了
Initialization¶
思考
从父类继承而来的子类,会拥有父类的成员变量和函数,也会有自己特制的成员变量和函数,那么他们都该如何进行初始化呢?
Example
在子类中,如果我们只初始化自己的成员变量,那么会发生报错:
这是因为我们没给父类进行初始化,编译器走默认构造函数,却发现我们也没有定义默认构造函数,因此,我们需要在子类的构造函数当中也顺便执行父类的构造函数:
这里我们同时也加上了子类的析构函数,也可以看到程序这些函数的运行顺序。
根据上面的例子,我们可以有:
- 子类在初始化时也需要调用父类的构造函数,如果父类的构造函数不是默认的也需要在子类调用
- 基类的构造函数最先执行,然后是派生类的构造函数
另外,如果我们在子类中重定义成员函数,那么其他父类的重载函数都会变得不可访问