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. 抽象类包含纯虚函数,不能实例对象,强制子类实现接口。

相关推荐
aqiu11111114 分钟前
【C++算法打怪专栏】LeetCode 402. 移掉 K 位数字(单调栈 + 贪心)
c++·算法·leetcode
(Charon)20 分钟前
【C++面试】线程并发与异步:区别、实现原理及使用场景
开发语言·c++
AIFQuant34 分钟前
Python A股实时行情API接入:沪深股票数据与WebSocket推送实战
开发语言·python·websocket·金融·a股行情
2302_8057710743 分钟前
Day23:POM设计模式(封装)
java·开发语言·设计模式
十年Java程序媛1 小时前
Java String、StringBuilder、StringBuffer 底层原理|字符串拼接性能与线程安全
java·开发语言·spring boot·安全·面试
Cx330❀1 小时前
Qt 界面美化指南:从零掌握 QSS 核心机制与工程实践
开发语言·qt·ui·性能优化·图形渲染
可乐ea1 小时前
2000 个智能体把 Agent 重写成 Rust:编排流水线拆解
开发语言·后端·rust·多智能体协作·ai编程助手·智能体编排·rust重写
JMchen1 小时前
实战项目一——实现一个高性能图片滤镜App
android·c++·性能优化
我是人✓1 小时前
SpringMVC异常处理与拦截器实战揭秘
java·开发语言·后端
不是万能的豆学长1 小时前
排查Go服务40天后的内存泄漏问题
开发语言·后端·golang·go