C++ 的 struct 与 class:唯一的真实区别

一句话:它们是同一个东西,只差一个默认值:struct 的成员默认公有,class 的成员默认私有。继承默认值同理。其余一切 — 方法、构造函数、继承、模板 — 两者完全一样。

提示:浏览器引擎覆盖教学核心,暂不支持自定义 struct/class,以下代码请在桌面编译器上跑。概念本身是核心面试内容,往下读。

证明:换个关键字,访问权就变

struct PointS {
    int x;      // 公有(struct 默认)
    int y;
};

class PointC {
    int x;      // 私有(class 默认)
    int y;
};

int main() {
    PointS s;
    s.x = 1;    // 没问题 — x 公有

    PointC c;
    c.x = 1;    // 错误:'int PointC::x' 是私有的
}

这就是全部的机械区别。把例子的 class 改成 struct,错误消失。两个关键字再无其他不同。

两者什么都干得了

// 带方法、构造函数、私有成员的 struct:完全合法
struct BankAccount {
  private:
    double balance = 0;
  public:
    explicit BankAccount(double start) : balance(start) {}
    void deposit(double amount) {
        if (amount > 0) balance += amount;
    }
    double getBalance() const { return balance; }
};

// 当纯数据包用的 class:也合法,只是不合惯例
class Config {
  public:
    int width;
    int height;
};

既然可以互换,为什么两个都存在?历史与惯例。C++ 从 C 继承了 struct(C 里它只能装数据),又为面向对象加了 class — 然后把它们做成同一个构造,只差默认值。

真实代码库的惯例

嗅探法:随便乱赋公有成员会造出无意义的对象吗?会 → class。不会 → struct。

第二个容易被忘的默认值:继承

struct DerivedS : Base { };   // 默认公有继承
class  DerivedC : Base { };   // 默认私有继承

同一个关键字,同一个被翻转的默认值 — 只不过作用于继承而不是成员。实践中继承的访问级别反正都应该显式写,但面试官爱考这个细节。

相关面试题

  1. "C++ 里 struct 和 class 的区别?" — 成员与继承的默认访问级别;没有别的。(在 C 里答案完全不同:C 的 struct 不能有方法。)
  2. "struct 比 class 快吗?" — 不。同样的代码,同样的性能;只有默认访问不同。
  3. "什么时候特意选 struct?" — 被动聚合(点、颜色、DTO),以及需要 C 兼容布局的互操作场景。
  4. "什么是聚合(aggregate)?" — 粗略说:没有自定义构造/私有成员的 struct,能用花括号初始化:Point p {1, 2};。带不变量的类做不到,这是设计使然。
  5. "为什么要把成员设为私有?" — 让对象能保证自己的规则(不变量);公有数据意味着谁都能破坏它,而且以后想加校验就得改动所有调用方。

桌面编译器上练

  1. 敲上面 PointS/PointC 的证明,读一读 c.x = 1; 的完整报错。
  2. 把 PointC 换成 struct,确认错误消失 — 同样的代码,一个关键字。
  3. 写一个 class Temperature:私有 celsius,set(double) 拒绝低于 −273.15 — 这就是"有不变量",公有数据的 struct 保护不了的东西。

相关:传值、指针与引用(对象怎么进函数)、栈与堆(对象住哪)、15 道初学者面试题(本文是那里的第 14 题)。