10 继承和派生
派生与成员函数
| 特性 | 重载 (Overload) | 隐藏 (Hide) | 覆盖 (Override) |
|---|---|---|---|
| 作用域 | 同一个类或作用域内 | 派生类与基类之间 | 派生类与基类之间 |
| 函数名 | 相同 | 相同 | 相同 |
| 参数列表 | 必须不同 | 可以不同,也可以相同 | 必须完全相同 |
virtual 关键字 |
无关 | 无关 | 基类函数必须是 virtual |
| 目的 | 用同一个函数名处理不同类型/数量的参数 | 派生类屏蔽基类同名函数 | 实现运行时多态,改变父类行为 |
-
如果想调用基类被隐藏的函数,需要使用
基类名::前缀 -
运算符重载本质上是函数的重载,规则与函数相同,但是编译器总会为派生类自动生成
operator=,这会隐藏基类版本。
改变访问控制
-
基类中的public或protected成员,因使用protected或private继承访问控制而导致在派生类中的访问方式发生改变,可以使用“访问声明”恢复为原来的访问控制方式
using 基类名::成员名; -
通常 using 声明不改变访问权限(比如在命名空间或派生类中引入基类函数时,保持原权限)。但在类作用域内对基类成员使用 using 时,它会根据 using 出现的位置重新设定访问级别。using 声明写在哪个权限区,该成员就变成什么权限。
class Base {
private:
int val = 10;
public:
void show() { cout << val << endl; }
};
// 公有继承
class Derive : public Base {
public:
// using 提升基类私有成员到派生类public权限
using Base::val;
};
int main() {
Derive d;
d.val = 100; // 外部可访问,权限已改为public
d.show();
return 0;
}
- 屏蔽基类成员:
- 用 private/protected 继承 整体屏蔽,这是真正彻底屏蔽,外部完全不能访问
- 在 private/protected 权限区利用 using 降级,仍然可以通过
基类::访问。
- 用于继承对象的重命名:
- 目的:在派生类中选择更合适的术语命名继承成员。
- 方法:屏蔽旧函数,在派生类中定义新的函数,该函数调用旧函数。
- 使用基类构造函数:使用
using 基类名::基类名使用基类的各个构造函数。