public、private、protected仅控制类外访问权限,不改变内存布局或影响重载;public可被类内外及派生类访问,private仅本类内可访问,protected限本类及派生类内部访问,类外均不可访问。

public、private、protected 在类定义中的直接效果
它们只控制「谁能在类外访问该成员」,不改变内存布局、不参与函数重载、也不影响友元或模板特化。关键看访问发生的**位置**和**继承路径**。
-
public:类内、类外(通过对象/指针/引用)、派生类中都可直接访问 -
private:仅限本类内部访问;派生类不能访问,类外更不行 -
protected:本类内部 + 派生类内部可访问;但类外不可访问(哪怕通过派生类对象也不行)
继承时的权限变化:基类成员在派生类中的可见性
继承方式(public/private/protected)会“降级”基类成员的访问级别,且只影响派生类自身的视角,不影响原类定义。
- 基类
public成员 →public继承后仍是public;protected继承后变为protected;private继承后变为private - 基类
protected成员 →public或protected继承后仍为protected;private继承后变为private - 基类
private成员 → 任何继承方式下,派生类中都不可见(不是“变成什么”,而是“根本看不到”)
常见误用:以为 protected 允许外部通过派生类访问
这是最常踩的坑:protected 不等于 “对派生类的用户开放”。即使 B 继承自 A 且 A::x 是 protected,你也不能写 B b; b.x = 42; —— 因为 b.x 是在类外访问,而 protected 禁止所有类外访问。
只有在 B 的成员函数内部,才能写 this->x = 42; 或 other_b.x = 42;(前提是 other_b 是 B& 类型)。
立即学习“C++免费学习笔记(深入)”;
实际设计建议:何时选哪个
别纠结“语义”,盯住两个事实:能否被派生类实现依赖?能否被用户调用?
- 接口函数(供用户调用)→ 必须
public - 仅供派生类复用的钩子函数(如
on_init())→protected - 纯内部状态、绝不希望派生类碰的字段(如引用计数、缓存锁)→
private - 想禁止派生类访问,又不想完全隐藏(比如需要友元或
friend class协作)→ 还是private,别用protected冒充“受限 public”
class Base {
private:
int secret_; // 派生类看不到,连 sizeof(Base) 都不暴露它是否存
protected:
int hook_; // B::do_work() 可以读写,但 B b; b.hook_ = 0; ❌ 编译错
public:
void run() { do_work(); } // 用户可调
protected:
virtual void do_work() = 0; // 派生类必须实现,但用户不能直接调
};
记住:C++ 的访问控制是编译期检查,不提供运行时封装。真正要隐藏实现,靠的是 PIMPL 或类型擦除,不是靠 private。










