public、private、protected 的核心区别在于“谁有资格访问”:public 对所有代码开放,private 仅限本类及友元,protected 允许本类及派生类访问但禁止外部访问;继承方式会二次修饰基类成员可见性。

public、private、protected 的核心区别不在“能不能访问”,而在“谁有资格访问”——这直接决定封装边界和继承行为,写错一个访问符,可能让子类无法调用关键函数,或让外部意外修改内部状态。
public 成员:谁都能直接碰,但得想清楚后果
声明为 public 的成员(变量或函数)对任何代码都开放:类外对象可直接访问,派生类也能自由使用,友元函数同样不受限。
常见误用场景:
- 把内部状态变量(比如
_buffer_size)设为public,导致外部随意修改,破坏类不变量 - 在基类中把本该由子类重写的函数设为
public但没加virtual,造成静态绑定误用
建议只对真正需要暴露的接口(如 size()、push_back())用 public,且优先提供 const 版本(如 const T& at(size_t) const)。
立即学习“C++免费学习笔记(深入)”;
private 成员:连子类都不可见,彻底封死
private 是最严格的限制:仅当前类的成员函数和友元可以访问,派生类**完全看不到**这些成员——哪怕同名也不构成重定义或覆盖。
典型陷阱:
- 在基类中把数据成员设为
private,子类想扩展逻辑却无法读取原始值,被迫改用protected,结果破坏封装 - 误以为
friend class Derived能让子类访问private,其实 friend 关系不继承,必须显式声明每个友元
真正该用 private 的是:实现细节(如缓存变量、临时指针)、非虚辅助函数、构造/析构中的私有逻辑。
protected 成员:给子类开后门,但对外依然锁死
protected 是继承设计的关键:基类自身和所有派生类可访问,但类外代码(包括友元)一律禁止访问。
注意几个易混淆点:
- 派生类中通过
this->或基类名(如Base::val)可访问基类的protected成员,但不能通过基类对象访问(Base b; b.val = 1;报错) - 多重继承时,若两个父类都有同名
protected成员,子类需显式指定作用域,否则编译失败 -
protected构造函数允许派生类调用,但禁止外部创建对象——这是实现抽象基类的常用手法
适合放在这里的是:供子类复用的工具函数、需要被子类调整但不应暴露给用户的字段(如 _state)、虚函数的默认实现。
继承方式如何影响 protected 和 private 成员的可见性
基类成员的访问权限在派生类中**不是固定不变的**,会受继承方式(public/protected/private)二次修饰:
- 以
public继承:基类public→ 派生类public;protected→protected;private→ 不可访问(消失) - 以
protected继承:基类public和protected都变成派生类的protected;private仍不可访问 - 以
private继承:基类所有非private成员全变为派生类private;外部彻底不可见
这意味着:即使你把成员设为 protected,若用 private 方式继承,它在派生类里就退化成 private,孙子类将无法再访问——这种“权限收缩”常被忽略,尤其在模板基类或策略类中容易引发编译错误。










