C++封装的核心是用private/public明确数据访问边界,防止非法修改;必须通过带校验的public方法控制访问,避免裸露成员变量;class默认private更安全,接口一旦发布即成契约,不可随意变更。

C++ 封装不是“把代码包起来”就完事,而是用 private / public 明确划出“谁可以碰数据”的边界——没这个边界,BankAccount 的 balance 就可能被任意赋值成负数或超大值,没人拦得住。
为什么不能直接 public 成员变量?
直接暴露成员变量(比如 int balance;)等于把银行金库大门焊死之后又把钥匙发给所有人。常见错误现象包括:
- 外部代码绕过校验逻辑,比如
acc.balance = -999999;导致账户余额非法 - 后续想加日志、审计、单位转换等逻辑时,所有已存在的赋值点都得改,牵一发而动全身
- 调试时无法断点拦截对字段的修改,只能靠全局搜索找所有
.或->赋值位置
正确做法是把字段设为 private,只留 public 的 deposit()、withdraw() 等方法控制入口。
private 字段 + public 方法怎么写才不踩坑?
关键不在“有没有 getter/setter”,而在“有没有业务语义”。比如温度类里,setCelsius() 带绝对零度校验,但 setFahrenheit() 就不该裸露——它应该转成摄氏再存,而不是另开一个字段。
立即学习“C++免费学习笔记(深入)”;
实操建议:
- 字段一律
private,哪怕只是临时缓存(如mutable double cached_volume;也要明确标注) - 避免无脑生成
getXXX()/setXXX():如果某个字段根本不该被外部读或写,就不提供对应接口 - setter 必须做输入校验,且校验失败时不静默吞掉错误(比如返回
bool或抛std::invalid_argument) - getter 如果返回内部引用(如
const std::string& getName() const),要确认该引用不会因对象修改而失效
class 默认 private,struct 默认 public ——这个差异真会影响代码吗?
会,而且经常在跨团队协作或第三方库集成时暴露。典型场景:
- 你用
struct Config { int timeout; };定义配置,别人直接c.timeout = 30;,后来你想加超时范围检查,就得全量替换所有调用点 - 继承时更危险:
class Base { int x; };的x对派生类不可见;但若误写成struct Base { int x; };,派生类就能直接访问x,破坏封装意图 - 模板元编程中,某些 trait(如
std::is_standard_layout)对class和struct行为一致,但人眼识别成本陡增
建议:除非明确需要 POD 类型且无逻辑约束(如纯数据传输结构体),否则统一用 class,显式写出 public: 区块。
封装不是终点,而是接口稳定性的起点
最容易被忽略的一点:封装后,public 接口一旦发布,就几乎不能删、不能改参数顺序、不能降级访问权限。比如你写了 public: void setRate(double r);,后续想改成 void setRate(double r, bool is_annual = true); 还能兼容,但若删掉这个函数,所有调用方都会编译失败。
所以真正难的不是写 private,而是想清楚哪些行为必须长期支持、哪些只是临时便利——这决定了你的类到底是个“工具”,还是个“契约”。


















