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 不等于 “对派生类的用户开放”。即使 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。