Struct和class在c++中功能完全一致,唯一区别是默认访问权限和默认继承方式;语义上struct用于数据聚合,class用于封装对象。

struct 和 class 在 C++ 里到底能不能互换?
能,但默认访问权限不同——这是唯一实质区别,其余所有功能(构造函数、继承、虚函数、模板参数、运算符重载)两者完全一致。
你写 struct S { int x; }; 等价于 class S { public: int x; }; ;而 class C { int y; }; 等价于 class C { private: int y; }; 。编译器眼里它们是同一类语法构造,只是默认封装策略相反。
- 别指望用
struct绕过封装:加了private:就和class一样不可见 - 别以为
class更“高级”:空class和空struct大小都是 1 字节(不是 0),内存布局无差异 - 继承时也只差一个默认值:
struct D : B默认是public继承,class D : B默认是private继承
什么时候该用 struct,什么时候必须用 class?
没有强制规定,但行业共识很清晰:看语义,不看功能。
struct 用于“数据聚合体”——字段公开、无隐藏逻辑、不打算被继承、构造/析构极简(甚至隐式);class 用于“对象”——需要控制状态变更、有不变式、依赖构造函数初始化、可能参与多态体系。
立即学习“C++免费学习笔记(深入)”;
- 适合
struct:坐标点Point { double x, y; }、配置项Config { int timeout; std::String host; }、POD 类型(如std::tuple内部) - 适合
class:DatabaseConnection(需资源管理)、Widget(有绘制/事件逻辑)、任何带virtual函数或非 trivial 析构的类型 - 踩坑点:把含
std::unique_ptr或自定义析构的类型硬写成struct,容易让人误判其生命周期责任
定义 struct 时最容易漏掉的三件事
不是语法错误,但会埋下维护雷——尤其在团队协作或后期扩展时。
- 忘记显式写
public:或private::虽然默认是public,但一旦中间插入私有辅助函数或成员,权限边界立刻混乱,建议统一显式标注 - 忽略构造函数一致性:比如
struct Rect { int x, y, w, h; };允许Rect r = {};零初始化,但如果后续加了Rect(int x, int y) : x(x), y(y) {},就变成非聚合类型,{}初始化失效 - 没考虑 ABI 兼容性:C++20 前,
struct若含虚函数或虚基类,就不再是标准 layout 类型,不能安全地和 C 接口二进制互通;这点class同样受限,但用struct的人更容易忽略
从 C struct 迁移到 C++ struct 的常见断点
C 代码直接扔进 C++ 编译器大概率能过,但行为可能已悄然改变。
- C 中
sizeof(struct {})是未定义行为(空结构体非法),C++ 中合法且为 1 —— 如果你依赖 C 的“空结构体报错”做编译期断言,得改用static_assert(sizeof(S) > 0) - C 中结构体变量声明必须带
struct关键字(struct Foo f;),C++ 允许省略(Foo f;),但混用头文件时若 C 接口被 C++ 包含,要小心命名空间污染 - C 中不能定义函数指针以外的函数,C++ 中可直接写成员函数;但别在
struct里塞太多逻辑——它不是 class 的廉价替代品,而是信号:这里应该简单
真正难的不是语法选择,而是判断这个类型将来会不会长出行为。一开始用 struct 没问题,等它开始需要保护字段、校验输入、管理资源时,就该果断重构为 class——别硬撑。