在C++中,struct本质上和class类似,只是默认访问权限为public,因此也可以像class一样定义构造函数,配合初始化列表完成成员变量的初始化,这种方式比传统的逐个赋值更高效,也能适配更多特殊成员场景。

一、C++ struct构造函数的常规写法
struct的构造函数没有返回值,函数名和struct名称一致,可以定义无参构造函数、带参构造函数,也可以设置默认参数,和普通类的构造函数写法基本一致。
1. 基础构造函数示例
下面是一个简单的坐标结构体,包含无参和带参两种构造函数:
#include <iostream>
using namespace std;
// 定义坐标结构体
struct Point {
int x;
int y;
// 无参构造函数,初始化x和y为0
Point() : x(0), y(0) {}
// 带参构造函数,通过参数初始化x和y
Point(int a, int b) : x(a), y(b) {}
// 带默认参数的构造函数
Point(int a = 0, int b = 0) : x(a), y(b) {}
};
int main() {
Point p1; // 调用无参构造函数
Point p2(10, 20); // 调用带参构造函数
Point p3(5); // 调用带默认参数的构造函数,y使用默认值0
cout << "p1: (" << p1.x << "," << p1.y << ")" << endl;
cout << "p2: (" << p2.x << "," << p2.y << ")" << endl;
cout << "p3: (" << p3.x << "," << p3.y << ")" << endl;
return 0;
}
2. 构造函数的作用
自定义构造函数可以让struct在创建实例时直接完成初始化,避免后续单独赋值,同时可以校验传入参数的合法性,比如限制坐标值不能为负数等。
二、初始化列表的语法与使用规则
初始化列表位于构造函数参数列表之后,函数体之前,以冒号开头,多个成员初始化用逗号分隔,语法格式为:
构造函数名(参数列表) : 成员1(初始值1), 成员2(初始值2), ... { 函数体 }
1. 初始化列表的初始化顺序
初始化列表中成员的初始化顺序和列表中的书写顺序无关,而是由struct中成员变量的声明顺序决定的。看下面的示例:
#include <iostream>
using namespace std;
struct Demo {
int a;
int b;
// 初始化列表先写b再写a,但实际先初始化a,再初始化b
Demo(int x) : b(x), a(b) {}
};
int main() {
Demo d(10);
cout << "a: " << d.a << ", b: " << d.b << endl; // 输出a为随机值,b为10
return 0;
}
上面的代码中,a声明在b之前,所以初始化时先给a赋值,此时b还没有被初始化,是随机值,因此a会被赋值为随机值,之后再给b赋值为10,最终结果不符合预期。因此写初始化列表时,最好和成员声明顺序保持一致,避免逻辑错误。
2. 初始化列表的优势
- 效率更高:对于非内置类型成员,初始化列表是直接初始化,而构造函数函数体内赋值是先默认构造再赋值,多一次额外操作。
- 支持特殊成员初始化:const成员变量、引用成员变量必须在初始化列表中初始化,无法在构造函数函数体内赋值。
三、初始化列表的必用场景
1. const成员变量初始化
struct中的const成员变量一旦初始化后就不能修改,因此必须在初始化列表中完成初始化:
#include <iostream>
using namespace std;
struct Student {
const int id; // const成员变量
string name;
// 必须在初始化列表中初始化id
Student(int stuId, string stuName) : id(stuId), name(stuName) {}
};
int main() {
Student s(1001, "张三");
cout << "学号: " << s.id << ", 姓名: " << s.name << endl;
return 0;
}
2. 引用成员变量初始化
引用成员必须在创建时绑定对象,也只能在初始化列表中初始化:
#include <iostream>
using namespace std;
struct RefDemo {
int& refNum; // 引用成员变量
RefDemo(int& num) : refNum(num) {}
};
int main() {
int num = 5;
RefDemo d(num);
cout << "refNum的值: " << d.refNum << endl; // 输出5
num = 10;
cout << "修改后refNum的值: " << d.refNum << endl; // 输出10,引用跟随变化
return 0;
}
四、不同初始化方式对比
下面是几种常见struct初始化方式的对比:
| 初始化方式 | 适用场景 | 优势 | 劣势 |
|---|---|---|---|
| 默认初始化+逐个赋值 | 简单结构体,成员少 | 写法简单,易理解 | 可能遗漏赋值,效率低 |
| 初始化列表初始化(C++11及以上) | 无需自定义构造函数的场景 | 代码简洁,无需额外定义构造函数 | 无法做参数校验,不适合复杂逻辑 |
| 自定义构造函数+初始化列表 | 需要参数校验、特殊成员初始化场景 | 灵活可控,支持特殊成员,效率高 | 需要额外定义构造函数 |
五、注意事项
- 如果struct定义了自定义构造函数,编译器不会再生成默认的无参构造函数,此时如果需要创建无参实例,必须显式定义无参构造函数。
- 初始化列表中的初始值可以是表达式,只要表达式的结果类型和成员类型匹配即可。
- 构造函数可以重载,根据需要定义多个不同参数的构造函数,适配不同的初始化场景。
C++_struct构造函数初始化列表结构体初始化修改时间:2026-06-23 03:45:21