C++98下如何初始化类中的结构体成员?
解决C++98下结构体成员初始化的警告问题
嘿,我来帮你搞定这个问题!首先得说清楚:你代码里的bar({0})是C11才引入的扩展初始化列表语法,C98根本不支持,所以编译器才会抛出那个警告。而且还有个小错误:main里你用指针thing访问成员的时候,应该用->而不是.,不然会直接编译失败。
接下来给你几种C++98兼容的方案,都能保证bar.z被初始化为0,还不会有警告:
方案1:利用值初始化(最简单)
C++98里,对POD类型(比如你这个foo结构体,全是int成员)用bar()进行值初始化,会自动把所有成员清零。直接修改构造函数的初始化列表就行:
myClass::myClass() : bar(), baz(0) { // something else. }
这样bar.x、bar.y、bar.z都会被初始化为0,完全符合你的需求,代码也简洁。
方案2:显式初始化每个结构体成员
如果你想更明确地控制每个成员的值(比如以后要改初始值更方便),可以在构造函数里逐个赋值:
myClass::myClass() : baz(0) { bar.x = 0; bar.y = 0; bar.z = 0; // something else. }
这种方式一目了然,适合需要单独调整成员初始值的场景。
方案3:给结构体添加构造函数
给foo结构体加一个默认构造函数(或者带参数的),这样就能在myClass的构造初始化列表里直接调用它:
struct foo { int x; int y; int z; // 默认构造函数,把所有成员初始化为0 foo() : x(0), y(0), z(0) {} // 可选:带参数的构造函数,方便以后灵活初始化 foo(int a, int b, int c) : x(a), y(b), z(c) {} }; // 然后myClass的构造函数可以这么写 myClass::myClass() : bar(), baz(0) { // 或者如果用带参数的构造函数:bar(0, 0, 0) // something else. }
这种方式更符合面向对象的风格,如果你以后需要给foo添加更多逻辑,扩展起来也方便。
方案4:用memset初始化整个结构体
如果你的foo结构体成员很多,逐个初始化太麻烦,可以用memset直接把整个结构体清零(注意:只有POD类型才能这么用,你的foo完全符合):
#include <cstring> // 要包含这个头文件用memset myClass::myClass() : baz(0) { memset(&bar, 0, sizeof(bar)); // something else. }
这种方式效率高,适合成员数量多的POD结构体,但要注意如果结构体里有非POD类型(比如std::string),绝对不能用这个方法。
最后别忘了修正main里的访问错误:把thing.bar.z改成thing->bar.z,不然编译器会报错说你在指针上用了.操作符。
内容的提问来源于stack exchange,提问作者SF.




