跳转至

💡 一分钟速览:通过可编译示例比较 C++ struct 与 class 的默认成员访问、默认继承方式,并说明何时选择两者以及聚合类型的常见误解。

最后更新:2026-10-13

C++ struct 与 class 有什么区别?

在 C++ 中,两者都定义类类型,都支持构造函数、成员函数、模板、继承和虚函数。语言规则上的区别是**成员的默认访问权限**和**基类的默认继承方式**;团队中的用法习惯是另一回事。

省略访问说明时 struct class
成员 public private
基类 public private

成员访问:第一个默认值

struct Open {
    int value = 1;          // 默认 public
};

class Closed {
    int value = 1;          // 默认 private
public:
    int get() const { return value; }
};

int main() {
    Open a;
    Closed b;
    // b.value = 2;         // 错误:私有成员
    return a.value == b.get() ? 0 : 1;
}

显式写出 public: 或 private: 就会覆盖默认值。struct 可以隐藏成员,class 也可以公开成员。关于 C 语言结构体及名称查找的更多区别,参见 C 与 C++ 的 struct。

继承方式:第二个默认值

#include <type_traits>

struct Base {};
struct PublicChild : Base {};  // 等同于 : public Base
class PrivateChild : Base {};  // 等同于 : private Base

static_assert(std::is_base_of_v<Base, PublicChild>);
static_assert(std::is_base_of_v<Base, PrivateChild>);
static_assert(std::is_convertible_v<PublicChild*, Base*>);
static_assert(!std::is_convertible_v<PrivateChild*, Base*>);

int main() {}

用 c++ -std=c++17 -Wall -Wextra struct_class.cpp 编译。PrivateChild 依然继承了 Base,只是外部代码不能隐式地把它的指针转成 Base*。在公开接口中,若继承方式对读者有意义,建议明确写出 public 或 private。

struct 一定是纯数据聚合吗?

不是。“公开的数据记录用 struct,维护不变量的类型用 class”是一种常见约定。是否为聚合类型还取决于构造函数、访问权限、基类及虚函数等条件,不能只看关键字。下面两个类型在 C++17 中都是聚合:

#include <type_traits>

struct Point { int x; int y; };
class Pair {
public:
    int first;
    int second;
};

static_assert(std::is_aggregate_v<Point>);
static_assert(std::is_aggregate_v<Pair>);

int main() {
    Point p{1, 2};
    Pair q{1, 2};
    return p.x == q.first ? 0 : 1;
}

实际如何选择?

  • 成员本来就是公开接口的简单数据记录,通常用 struct。
  • 需要通过操作维护不变量、限制成员的直接修改,通常用 class。
  • 不要让读者猜公开 API 的访问或继承意图;有必要时显式写出权限。

关键字本身不会带来特殊性能,也不会把 C++ 类型变成“C 风格结构体”。进一步阅读 explicit 转换和智能指针函数参数。

参考资料

关于作者

个人公众号:

C++ struct 与 class 的区别:默认访问和继承 | C++那些事

相关主题

评论