struct最基本形式是"struct 名字 {成员};”,末尾必须加分号;默认public,支持成员函数和继承;C++11起可设默认值但仅限=语法;匿名struct用途有限,嵌套struct需注意作用域和ODR。

struct 关键字后面直接跟结构体名和花括号
定义 struct 最基本的形式就是写 struct、名字、一对 {},里面放成员变量。不需要额外声明或关键字修饰,也不用像类那样区分 public/private(默认全是 public)。
常见错误是漏掉分号——struct 定义末尾必须有分号,否则编译报错:expected ';' after struct definition。
-
struct Point { int x; int y; };✅ 正确,末尾有分号 -
struct Point { int x; int y; }❌ 编译失败 - 成员变量可以是任意类型:内置类型、数组、指针、其他
struct,甚至std::string(需包含<string>)
定义同时声明变量要小心作用域和初始化
可以在 struct 定义末尾直接跟变量名,实现“定义+声明”一步到位,但容易混淆作用域和生命周期。
比如:struct Config { int port; bool debug; } g_config; 这样定义后,g_config 是全局变量;如果写在函数里,就是局部变量。
立即学习“C++免费学习笔记(深入)”;
- 这种写法不能用于模板或需要前向声明的场景
- C++11 起支持在定义时给成员加默认值:
int port = 8080;,但要注意:只有=初始化语法可用,{}或()初始化会触发编译错误(除非用聚合初始化或构造函数) - 如果后续要单独定义变量,推荐分开写:
struct Config { ... }; Config cfg1, cfg2;,更清晰可控
struct 和 class 几乎没区别,但默认访问权限不同
在 C++ 里,struct 和 class 语义上唯一实质差异就是默认成员访问权限:struct 默认 public,class 默认 private。其余所有能力(继承、成员函数、构造函数、运算符重载等)完全一致。
所以别被“struct 只能存数据”这种过时说法误导。你可以给 struct 加构造函数、operator==、甚至虚函数——只要逻辑合理。
- 想快速建一个纯数据容器?用
struct更自然,省得写public: - 想封装行为+状态且强调封装性?用
class是惯例,但不是强制 - 继承时也一样:
struct Derived : Base {}默认是public继承;class Derived : Base {}默认是private继承
匿名 struct 和嵌套 struct 的使用边界
匿名 struct(没名字、只声明变量)在 C++ 中合法但受限:不能作为函数参数类型、不能取地址、不能有静态成员,实际用途极少,多数情况是误写。
嵌套 struct 常见于封装内部细节,比如:struct Parser { struct Token { int type; }; Token next_token(); };。这时 Token 作用域在 Parser 内,外部要用 Parser::Token。
- 嵌套
struct不能直接访问外层的非静态成员(没有隐式this) - 如果嵌套结构体需要频繁实例化,又不想暴露名字,可配合
using类型别名简化:using Token = struct { int type; }; - 跨编译单元使用嵌套
struct时,注意 ODR(One Definition Rule):定义必须完全一致,否则链接期可能出问题
struct 看似简单,但和默认权限、初始化规则、ODR、模板实例化这些机制咬得很紧——写错一个分号或一个默认值语法,就可能卡在编译器报错里半天。


















