默认继承方式下class为private、struct为public;public继承保持is-a关系,private/protected继承切断该关系且95%场景应避免。

不写继承方式时 class 默认是 private,struct 是 public
很多人写 class Derived : Base 以为就是“正常继承”,结果发现基类的 public 成员在派生类里变不可访问了——不是编译器坏了,是 C++ 规则:用 class 定义派生类时,省略继承方式就等价于 :private Base。
这意味着基类所有原本 public 和 protected 成员,在派生类中全变成 private;外部更无法通过派生类对象调用基类接口。这种“静默降权”极难排查,尤其当基类接口本该被使用者调用时。
-
class派生类不写继承方式 → 实际是private继承 -
struct派生类不写继承方式 → 实际是public继承 - 即使你只打算内部用,也建议显式写出
:public或:protected,避免后续有人误改class/struct关键字导致权限突变
public/protected/private 继承直接决定成员在派生类中的可见性
继承方式不是“要不要继承”,而是“以什么权限继承”。它和基类成员原有访问限定符共同作用,最终决定该成员在派生类内的实际可访问级别,规则是:min(基类成员原有权限, 继承方式),其中 public > protected > private。
比如基类有个 protected 成员 _data:
-
public继承 → 派生类中仍是protected(可访问) -
protected继承 → 还是protected(可访问) -
private继承 → 变成private(仍可访问,但外部完全不可见)
再比如基类 public 函数 init():
-
public继承 → 派生类对象能直接调用d.init() -
private继承 →d.init()编译失败,只能在派生类内部调用
private 和 protected 继承会切断 is-a 关系,且几乎无法被多态使用
如果你写了 class Dog : private Animal,那 Dog 就不是一种 Animal——不能把 Dog* 转成 Animal*,也不能传给接受 Animal& 的函数。这违背了继承最核心的语义目的。
实际项目里,95% 以上的继承都该是 public。而 private 继承本质是“借代码实现”,但此时组合(has-a)通常更清晰、更安全;protected 继承几乎没有合理场景,容易让人误以为是“半公开”,实则封闭性更强。
-
private继承:基类接口彻底对用户隐藏,仅用于实现复用(推荐改用组合 + 成员对象) -
protected继承:基类public接口在派生类中降为protected,子类用户无法调用,连多态都断掉 - 只要你想表达“是一个”,就必须用
public继承,否则后续所有虚函数、向上转型、接口统一都将失效
基类 private 成员永远不可见,写不写继承方式都不影响这点
新手常误以为“改成 public 继承就能访问基类 private 成员”,这是错的。private 成员在任何继承方式下,对派生类都是不可见的——它们确实被继承进了对象内存布局,但语法上禁止一切直接访问。
如果派生类需要访问基类的某些数据,正确做法是:
- 把基类成员从
private改成protected(前提是语义允许) - 或在基类提供
public/protected的访问函数,让派生类通过函数间接操作 - 不要指望靠换继承方式绕过
private限制
真正容易被忽略的是:private 成员虽不可见,却仍参与对象大小计算、构造/析构顺序、内存布局——你在调试时看到它存在,但代码里碰不到它,这种“幽灵存在”最容易引发误解。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











