struct成员默认public,class默认private;struct继承默认public,class默认private;struct倾向POD类型和C兼容,class强调封装与资源管理。

默认访问权限不同:不写 public 就会出问题
这是唯一影响编译行为的语法级区别。struct 成员默认 public,class 默认 private。你写 struct S { int x; };,外部可以直接用 s.x = 42;;但换成 class C { int x; };,同一行代码直接报错:error: 'int C::x' is private。
- 修复方式很简单:显式加
public:或private:,两者立刻行为一致 - 新手常踩的坑:把
class当成“必须封装”,结果忘了加public:导致接口不可见;或把struct当成“不能有函数”,其实它完全可以定义构造函数、operator==甚至虚函数 - 真正该警惕的不是能不能,而是“为什么这里用了
struct却有一堆private成员”——这会让协作者困惑设计意图
继承时默认方式不同:影响多态和模板推导
不写继承修饰符时,struct D : B {} 等价于 struct D : public B {};而 class D : B {} 等价于 class D : private B {}。这个差异在接口传递和模板匹配中会悄悄暴露:
-
private继承会切断基类的公有接口,比如class D : B {}后,D对象无法隐式转为B&,传给接受B&的函数会编译失败 - 模板特化时关键字必须严格匹配:如果声明是
template,特化就必须写struct Container; template struct Container,写成{}; template class Container会报错{}; - 实际项目中建议始终显式写出
public/private,避免靠默认值埋雷
语义与 ABI 兼容性:选错关键字可能影响二进制接口
虽然功能完全等价,但社区约定深刻影响实际使用:
-
struct天然倾向 POD 类型(无虚函数、无用户定义构造/析构),适合跨语言交互(如 C 接口)、内存拷贝(memcpy)、网络协议结构体 -
class暗示封装逻辑,比如std::vector有私有指针、自定义析构、分配器策略——看到它你就该想到资源管理 - ABI 层面:带虚表或非 trivial 构造的
class可能改变对象布局;而纯struct更易保证标准布局(standard-layout),这对序列化、reinterpret_cast很关键
什么时候该用 struct,什么时候该用 class
别纠结“能力边界”,看设计意图:
立即学习“C++免费学习笔记(深入)”;
- 用
struct:配置项(struct Config { std::string host; int port; };)、几何类型(struct Vec3 { float x,y,z; };)、C 兼容结构(struct sockaddr_in)——强调“它是什么” - 用
class:需要控制生命周期(class FileHandle)、校验输入(class Temperature { private: double celsius; public: void set_celsius(double); };)、支持多态(有虚函数)——强调“它能做什么” - 最危险的信号:一个
struct里既有private:成员,又有复杂构造函数,却没有注释说明为什么破例——这种模糊会拖慢整个团队的理解成本
真正的复杂点不在语法,而在团队对“struct 意味着简单数据”这一共识的依赖程度。一旦打破,就得靠文档和命名来补救,而人总是倾向于跳过文档。











