private关键字必须写在类定义内部且紧邻访问控制符,仅对后续声明生效直至下一访问说明符;不写时class默认private,struct默认public;私有成员须在类体中直接声明,不可在函数内或类外定义。

private 关键字必须写在类定义内部,且紧挨访问控制符
私有成员变量不是靠命名约定(比如加下划线)实现的,而是由 private: 这个访问说明符严格控制。它只对后续声明起作用,直到下一个访问说明符出现为止。
常见错误是把 private: 写在类外、或误写成 private()、private void 等——这些都会直接报错,比如 error: expected unqualified-id before ‘:’ token。
-
private:后面不能跟分号 - 同一类中可以多次出现
public:、private:,顺序不限,但每个说明符只影响其后的成员 - 不写任何访问说明符时,默认是
private:(仅对class有效,struct默认是public:)
成员变量声明位置:类体内部,不能在函数里或全局作用域
私有变量必须作为类的直接成员声明,不能塞进构造函数、成员函数里,也不能在类外用 MyClass::m_data 形式“补定义”——那会变成静态成员或链接错误。
典型错误现象:‘m_value’ was not declared in this scope,往往是因为手滑把变量写在了某个函数花括号内,或者漏掉了 private: 导致编译器当成全局查找。
立即学习“C++免费学习笔记(深入)”;
- 正确写法:
class Counter { private: int m_count; public: Counter() : m_count(0) {} }; - 错误写法:
void inc() { int m_count; m_count++; }—— 这只是局部变量,和类封装无关 - 成员变量不能带初始化器(C++11 前),但 C++11 起支持
int m_count = 0;,注意这和构造函数初始化列表语义不同
为什么不能直接访问 private 成员:编译期检查,不是运行时保护
私有性是编译器强制的语法约束,不是内存隔离机制。一旦绕过(比如通过指针偏移、友元、或把头文件改成 public:),照样能读写——但这不代表它“不安全”,而是说它的作用是明确接口边界、防止误用。
实际开发中容易忽略的一点:子类无法访问父类的 private 成员,哪怕继承方式是 public。想让子类用,得用 protected:。
- 外部代码访问
obj.m_count会报错:‘int Counter::m_count’ is private within this context - 友元函数/类可以访问,但需显式声明:
friend void inspect(const Counter&); - 反射、序列化库(如 cereal)依赖这种访问控制,它们通过特化或宏“合法绕过”,不是 hack
封装不只是加 private:配套需要 getter/setter 或行为抽象
光把变量设为 private 只完成一半工作。如果立刻配上一堆无逻辑校验的 get_xxx() / set_xxx(),其实没提升多少安全性,还可能暴露内部结构。
真正有用的封装,是把“能做什么”变成接口,而不是“值是多少”。比如温度类不该暴露 get_celsius() 和 set_celsius(),而应提供 raise_by(2.5) 或 is_fever()。
- 简单类型(如
int)若无业务约束,有时用public成员更清晰(尤其在 POD/数据类中) - 涉及单位转换、范围检查、状态同步的字段,才值得用
private+ 方法封装 - 过度封装会导致调用链变长、调试困难,比如
obj.data().inner().value().get()这种“俄罗斯套娃”访问











