C++继承与多态核心笔记|菱形继承、组合、虚函数、纯虚函数一网打尽

一、继承模型

1. 单继承

一个派生类只有一个直接基类,就是单继承。

2. 多继承

一个派生类有两个及以上直接基类,就是多继承。 内存布局:先继承的基类在前面,后继承的基类在后面,派生类自身成员放在最后。

3. 菱形继承(钻石继承)

菱形继承是多继承的特殊情况。

  • 问题 :普通多继承会造成数据冗余、二义性,公共基类成员存多份。

  • 解决:虚继承 virtual:虚继承之后公共基类只保留一份。

Java 直接不支持多继承,直接规避菱形继承问题,工程实践尽量避免设计菱形继承。

二、多继承指针偏移问题

复制代码
class Base1 { public: int _b1; };
class Base2 { public: int _b2; };
class Derive : public Base1, public Base2 { public: int _d; };

int main()
{
    Derive d;
    Base1* p1 = &d;
    Base2* p2 = &d;
    Derive* p3 = &d;
    return 0;
}
  • p1指向对象起始地址,对应Base1子对象;

  • p2指向Base2子对象,指针会向后偏移

  • p3指向完整派生类对象起始地址。

所以 p1 != p2,p1 == p3。多继承向上转型,不同基类指针地址不一定相等。

三、继承和组合

本质:都是复用成员。

  1. public 继承:is‑a 派生类对象本质就是一个基类对象,属于白箱复用。 子类可以访问父类保护成员,耦合度高,父类改动会强烈影响子类。

  2. 组合:has‑a 把类对象作为另一个类的成员,属于黑箱复用。 内部细节对外不可见,类之间依赖弱,耦合度低

✅工程原则:优先使用组合,而不是继承

  • is‑a 关系,用继承;

  • has‑a 关系,优先组合;

  • 需要实现多态,必须使用继承。

高内聚、低耦合是软件工程核心追求。

四、多态

1. 多态两个必要条件

  1. 基类指针 / 引用调用函数;

  2. 调用的是虚函数,派生类完成虚函数重写 (覆盖)。

2. 虚函数重写(三同)

派生类虚函数和基类虚函数,返回值、函数名、参数列表全部相同,叫重写。
小坑:派生类不加 virtual,只要满足三同,依然构成重写,语法允许,但可读性差,考试选择题高频坑点。

3. 虚析构函数

基类析构建议写为virtual虚析构。

  • 如果基类析构是虚函数,派生类析构自动构成重写,不管写不写 virtual。

  • delete 基类指针指向派生类对象,只有基类析构为虚,才会调用派生类析构,否则只会调用基类析构,派生类资源泄漏

五、重载、重写 (覆盖)、隐藏三大概念对比

  1. 重载:同一个作用域,函数名相同,参数列表不同。

  2. 重写 / 覆盖:继承体系,基类和派生类,虚函数,三同。

  3. 隐藏:派生类定义和基类同名函数,不管参数是否相同,基类同名函数直接被隐藏。

六、纯虚函数 & 抽象类

复制代码
virtual void func() = 0;
  1. 虚函数后面写=0,就是纯虚函数,可以不写函数体。

  2. 拥有纯虚函数的类叫抽象类

  3. 抽象类不能实例化对象

  4. 派生类必须重写全部纯虚函数,否则派生类也变成抽象类,也不能实例化。

抽象类强制约束派生类必须实现接口。


考点小结

  1. 菱形继承:普通继承造成二义性冗余,virtual虚继承解决;

  2. 多继承向上转型,不同基类指针地址会偏移,不一定相等;

  3. 优先组合,is‑a 才用继承;

  4. 多态两大条件:基类指针 / 引用 + 虚函数重写;

  5. 基类析构建议 virtual,防止派生类内存泄漏;

  6. 抽象类包含纯虚函数,不能实例对象,强制子类实现接口。

相关推荐
大白同学4212 小时前
初识Qt——创建第一个Qt项目
开发语言·qt
祈禾2 小时前
计算机组成原理之编译、汇编、链接、解释
开发语言·汇编·笔记·学习
吴声子夜歌2 小时前
正则指引——Ruby
开发语言·正则表达式·ruby
nnerddboy2 小时前
Rust教程06:ESP32-rust环境搭建
开发语言·后端·rust
nnerddboy3 小时前
Rust教程03:函数,控制流与所有权
开发语言·后端·rust
小龙报3 小时前
【优选算法】1.搜索插入位置 2.x的平方根
java·c语言·数据结构·c++·python·算法·蓝桥杯
linux修理工3 小时前
内存占用 99% 且 Java 程序较多的优化建议
java·开发语言
weixin_460443563 小时前
企业考试系统如何对接OA、钉钉和企业微信?SSO单点登录、组织同步与权限一致性设计
java·开发语言·数据库
nnerddboy3 小时前
Rust教程05:结构体,枚举与模式匹配
开发语言·网络·rust
小小尚@3 小时前
AE脚本-AE Actions v1.1.8 操作动作记录器
开发语言·前端·javascript·jupyter·postman