能解决同类数据结构与接口的重复定义,如person、student、teacher共用_name、_age、_tel及identity(),可提取至基类;但无法解决语义不同或职责不一致的“假重复”。

能解决「同类数据结构+同类接口」的重复定义问题,但不能解决逻辑差异大、职责不一致或仅字段名相同但语义不同的重复。
重复的成员变量和公共接口直接提取到基类
比如 Person、Student、Teacher 都有 _name、_age、_tel 和 identity() 方法,这些就可以统一收进 Person 类。派生类只需声明自己独有的部分(如 _stuNum 或 _title),不用再写一遍共用字段和函数。
- 基类中用
protected修饰共用成员,保证派生类可访问但外部不可直接改 - 共用函数(如
identity())在基类实现一次,子类可直接调用,也可用virtual预留重写空间 - 避免“抄代码式复用”:改一个字段名(比如把
_age改成_birthYear)只需动基类,不用逐个类搜替换
构造函数初始化逻辑重复时,用 using 声明继承
C++11 起支持 using Base::Base 让派生类自动获得基类构造函数签名。适用于派生类没新增必须初始化的成员,或新增成员有默认值的场景。
- 例如
Student只比Person多一个int _stuNum = 0,那using Person::Person就能让Student s("Alice", 20)正常工作 - 如果派生类有非默认初始化成员(如引用、const 成员、无默认构造的类成员),
using就失效,必须显式写构造函数 - 注意:
using只继承直接基类的构造函数,不支持间接继承(比如 A → B → C,C 不能用using A::A)
多继承中同名成员冲突?虚继承不是为“去重”,而是为“消歧”
菱形继承(如 Student 同时继承 Academic 和 Staff,二者又都继承 Person)会导致 Person 子对象被复制两份,引发二义性和内存冗余。这不是普通代码重复,是对象模型层面的结构问题。
-
virtual public Person的作用是让最终派生类只含一份Person子对象,解决调用Person::name时编译器不知道选哪条路径的问题 - 虚继承不减少你写的代码行数,它解决的是“即使写了继承,运行时仍出错”的底层一致性问题
- 虚基类的构造由**最派生类**负责调用,中间层即使写了初始化列表也会被忽略——这点极易踩坑
真正容易被忽略的是:继承只对「is-a」关系有效。两个类都有 string name,但如果一个是数据库表名、一个是用户昵称,强行塞进同一个基类,后期扩展(比如加校验规则、序列化方式)必然撕裂。这时候用组合或类型别名反而更稳。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











