在 C++公有继承 (public inheritance)场景下,赋值兼容原则 是面向对象多态特性的基础规则,也是实际开发中必须掌握的核心知识点。它定义了基类 与公有派生类 对象之间的赋值、转换规则,且这些转换是自动、安全、隐式的,无需强制类型转换。
一、核心概念
- 赋值兼容原则 :在公有继承中,派生类对象可以当作基类对象使用,基类的指针、引用可以指向、引用派生类对象。
- 前提条件 :必须是公有继承!私有继承、保护继承不满足该原则。
- 本质 :公有继承表达 is-a(是一个) 关系,派生类是基类的一种特例,因此可以自动向上匹配基类。
简单记:公有继承下,子类对象可以自动转换为父类对象。
二、赋值兼容的四种典型用法(重点)
我们先定义基类和公有派生类,用于演示:
cpp
#include <iostream>
using namespace std;
// 基类
class Base {
protected:
int a;
public:
Base(int x) : a(x) {}
void show() {
cout << "Base: a = " << a << endl;
}
};
// 公有派生类
class Derived : public Base {
private:
int b;
public:
// 初始化基类
Derived(int x, int y) : Base(x), b(y) {}
void show() {
cout << "Derived: a = " << a << ", b = " << b << endl;
}
};
1. 派生类对象 赋值给 基类对象
派生类对象可以直接给基类对象赋值,只会赋值基类成员,派生类独有成员会被截断。
cpp
int main() {
Derived d(10, 20); // 派生类对象
Base b = d; // 合法:派生类→基类(自动转换)
b.show(); // 调用基类方法,输出:Base: a = 10
return 0;
}
2. 派生类对象 初始化 基类引用
基类引用可以直接绑定派生类对象,引用的是基类部分,无截断、无拷贝。
cpp
Derived d(10, 20);
Base& ref = d; // 合法:基类引用指向派生类对象
ref.show(); // 调用基类方法
3. 基类指针 指向 派生类对象
基类指针可以直接指向派生类对象,这是多态的基础。
cpp
Derived d(10, 20);
Base* ptr = &d; // 合法:基类指针指向派生类对象
ptr->show(); // 调用基类方法
4. 派生类对象 作为函数参数(基类类型)
函数形参为基类对象 / 指针 / 引用时,可直接传入派生类对象,这是赋值兼容原则最常用的场景。
cpp
// 函数参数是基类引用
void print(Base& obj) {
obj.show();
}
int main() {
Derived d(30, 40);
print(d); // 直接传入派生类对象,自动转换
return 0;
}
三、核心规则总结
- 只能向上转换:派生类 → 基类(自动、安全)
- 不能向下转换 :基类 → 派生类(不允许隐式转换 ,强行转换需用
dynamic_cast,且有风险) - 仅公有继承有效:private/protected 继承会破坏赋值兼容原则
- 转换后只能访问基类成员 :指针 / 引用指向派生类对象后,无法直接访问派生类独有成员
错误示例(基类指针访问派生类成员):
cpp
Derived d(10,20);
Base* ptr = &d;
ptr->b; // 错误!基类没有b成员
四、为什么必须是公有继承?
公有继承 :表达 is-a(是一个)关系,派生类完全包含基类的所有公有 / 保护成员,外部可安全访问基类成员。
私有 / 保护继承 :表达 has-a(有一个)关系,基类成员在派生类中变为私有 / 保护,外部无法访问,不满足自动转换的安全性。
示例:私有继承无法赋值兼容
cpp
class Derived : private Base { ... };
Derived d;
Base b = d; // 错误!私有继承不允许转换
五、赋值兼容原则的意义
- 代码复用:一个函数可接收所有派生类对象,无需为每个子类写单独函数。
- 多态基础 :基类指针 / 引用指向派生类对象,配合虚函数实现运行时多态。
- 程序灵活:新增派生类时,基类接口无需修改,符合开闭原则。
六、易混点区分
-
赋值兼容 ≠ 类型相等 转换后只能用基类接口,不能用派生类独有成员。
-
向上转换安全,向下转换危险
- 向上:派生类→基类(自动,安全)
- 向下:基类→派生类(必须强转,不安全)
-
对象赋值会截断,指针 / 引用不会截断
- 对象赋值:派生类独有成员丢失
- 指针 / 引用:仅指向基类部分,对象本身无变化
总结(必背)
- 适用条件 :仅公有继承生效。
- 核心规则:派生类对象可自动转换为基类类型(对象、指针、引用)。
- 四种用法 :
- 派生类对象 → 基类对象
- 派生类对象 → 基类引用
- 派生类对象地址 → 基类指针
- 派生类对象 → 基类类型函数参数
- 核心价值:是 C++ 多态的前提,让代码更通用、更灵活。
赋值兼容原则是理解 C++ 继承与多态的必经之路,必须熟练掌握!