class默认private继承,struct默认public继承;该差异仅由派生类关键字决定,与基类类型无关,且影响所有基类的访问权限,建议始终显式声明继承方式以避免隐式行为风险。

class 默认 private 继承,struct 默认 public 继承
这是 C++ 中 class 和 struct 在继承行为上最直接、最常被忽略的差异。它不依赖于基类是 class 还是 struct,只取决于派生类型自身的声明关键字。
- 写
class D : B {}等价于class D : private B {}—— 基类B的公有成员在D中变成私有,外部无法通过D对象访问B的接口 - 写
struct D : B {}等价于struct D : public B {}—— 基类B的公有成员在D中仍为公有,可被D对象直接调用 - 这种默认方式会“穿透”混合继承:比如
class D : Base1, Base2中,Base1和Base2都按private继承;而struct D : Base1, Base2中,两者都按public继承 - 如果基类本身是
struct,而派生类是class,默认仍是private继承 —— 不会因为基类开放就自动放宽访问限制
struct 继承 class 时默认仍是 public,但可能触发访问错误
语法上允许 struct Derived : BaseClass {},且默认是 public 继承。但能否实际使用,取决于 BaseClass 自身的成员访问权限。
-
BaseClass的private成员永远不可见,无论继承方式如何 - 如果
BaseClass只有private或protected成员,即使Derived是struct并public继承,外部代码也无法访问这些成员 - 常见错误现象:
error: 'int BaseClass::x' is inaccessible—— 这不是继承方式错了,而是基类没把成员设为public或protected - 反过来,
class Derived : BaseStruct默认是private继承,会导致BaseStruct的public成员在Derived中变为private,外部调用失败
为什么这个区别容易被忽略?
因为绝大多数人显式写了继承方式(比如 class D : public B),掩盖了默认行为。但一旦省略,编译器就按关键字自动补全,而这个补全逻辑不统一。
- IDE 和静态分析工具通常不会高亮“缺失的继承方式”,所以错误往往在运行时或子类使用时才暴露
- 跨团队协作中,有人习惯写
struct表达 POD 类型,有人用class表达封装类型,但若继承链混用又不写明方式,语义和实际行为就可能错位 - 模板元编程中,
std::is_base_of_v<b d></b>返回true,不代表D能公开访问B的接口 —— 访问性由继承方式决定,而非继承关系本身
建议始终显式写出继承方式
这不是“最佳实践”的客套话,而是避免隐式行为引发维护风险的实际做法。
- 哪怕你 100% 确定要
public继承,也写成class D : public B或struct D : public B - 对
private或protected继承更要显式标注,否则后续修改者极易误判设计意图 - CI 流程中可加入 Clang-Tidy 规则
cppcoreguidelines-explicit-virtual-functions类似检查,但继承方式目前无标准 lint 规则,只能靠约定
public: 或一个 public 关键字,结果整个继承链的可见性悄然改变,而编译器不报错、测试也不覆盖——直到下游模块调用失败。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











