C++中struct改带构造函数的class后,列表初始化静态实例报错如何解决
带构造函数的类无法使用聚合初始化的问题解决
问题背景
原本用struct存储数据,部分实例作为头文件中的静态项直接初始化,部分通过程序动态填充数据。为了给部分成员设置默认值,将其改为带构造函数的class后,出现编译错误。
可正常运行的代码(struct版本)
struct ThisThing { int A; int B; }; static ThisThing TT1 = {1,2};
可正常运行的代码(无构造函数的class版本)
class ThisThing { public: int A; int B; }; static ThisThing TT1 = {1,2};
编译失败的代码(带自定义构造函数的class版本)
class ThisThing { public: ThisThing(){}; int A; int B; }; static ThisThing TT1 = {1,2};
报错信息
error: could not convert '{1, 2}' from '<brace-enclosed initializer list>' to 'ThisThing' 68 | static ThisThing TT1 = { 1,2 } | ^ | | | <brace-enclosed initializer list>
原因分析
C++中,{1,2}这种花括号初始化属于聚合初始化,仅适用于聚合类型。当你给类定义了任何自定义构造函数(哪怕是空构造函数),该类就不再被视为聚合类型,因此无法使用聚合初始化语法。
解决方案
针对你的实际场景(需要给部分int成员设默认值、存在2K缓冲区、同时支持静态初始化和动态创建填充),推荐两种可行方案:
方案1:添加参数化构造函数
保留默认构造函数来设置默认值,同时添加接受成员参数的构造函数,支持花括号初始化:
class ThisThing { public: // 默认构造函数:给需要默认值的成员赋初始值,缓冲区默认初始化 ThisThing() : A(0), B(0) {} // 参数化构造函数:支持花括号初始化语法 ThisThing(int a, int b) : A(a), B(b) {} int A; int B; char buffer[2048]; // 2K数据缓冲区 }; // 静态实例:调用参数化构造函数初始化 static ThisThing TT1 = {1,2}; // 动态实例:使用默认构造函数(成员带默认值) ThisThing* TT2 = new ThisThing(); // 动态实例:手动填充数据 TT2->A = 3; TT2->B = 4; // 填充缓冲区...
方案2:使用类内成员初始化(推荐)
无需定义构造函数,直接在类内给成员设置默认值,这样类依然属于聚合类型,既能保留默认值,又支持聚合初始化:
class ThisThing { public: int A = 0; // 给成员设置默认值 int B = 0; char buffer[2048]; // 缓冲区默认初始化 }; // 静态实例:仅初始化指定成员,未指定的用默认值 static ThisThing TT1 = {1,2}; // 静态实例:全部使用默认值 static ThisThing TT2; // 动态实例:使用默认值 ThisThing* TT3 = new ThisThing(); // 动态实例:自定义初始化部分成员 ThisThing TT4 = {5,6}; // 手动填充缓冲区或修改成员...
关于初始化列表构造函数的疑问
如果使用ThisThing(): A(0) {};这种带初始化列表的构造函数,情况不会有任何改善——只要存在自定义构造函数,类就不再是聚合类型,依然无法使用{1,2}的聚合初始化语法,还是会触发相同的编译错误。
内容的提问来源于stack exchange,提问作者CoreyCoop
相关产品推荐
相关产品推荐

