C++中在结构体内部声明另一结构体成员的正确方法
问题解答
你的现有写法虽然可以正常运行,但属于为了绕开编译报错搞的*“弯路”实现*,存在明显的冗余和不必要的性能开销,也完全不需要强制给所有成员先指定默认值再赋值。
你之前不得不写长初始化列表的原因
因为你为A自定义了带11个参数的构造函数之后,编译器不会再自动生成无参的默认构造函数。如果不在B的构造函数初始化列表里显式初始化a成员,编译器会尝试调用不存在的A::A()触发编译报错,你写一长串0本质是为了强行满足初始化要求,再后续用传入的参数覆盖,逻辑上完全多余。
现有代码的额外开销
你在B的构造函数中做了两步无效操作:
- 首先用11个0构造了一个临时的A对象初始化成员
a - 再用传入的
c_a通过拷贝赋值覆盖已经初始化完成的a
等于凭空多执行了一次A的构造+一次拷贝赋值操作,既冗余又降低性能。
正确简化写法
你完全可以直接用传入的c_a参数初始化成员a,不需要提前填默认值绕路:
struct B { public: A a; // 直接用传入的c_a初始化a,不需要提前设置默认值,也不会触发编译报错 B(A c_a) : a(std::move(c_a)) {} };
如果你的编译环境不支持C++11及以上标准,去掉std::move直接写a(c_a)也可以正常运行。
关于默认初始化的场景说明
只有当你需要用到结构体的默认构造逻辑(比如不传入参数就构造B的实例)的时候,才需要给成员设置默认值,此时你有两种更简洁的方案避免写长初始化列表:
- 把默认值的初始化逻辑封装到A内部,给A添加默认构造函数,外层调用时不需要再重复写一长串参数
- C++11及以上标准可以直接在A的成员声明处指定默认值:
int a = 0;,构造时没有传入对应参数就会自动用默认值初始化
内容的提问来源于stack exchange,提问作者Wusiki Jeronii
相关产品推荐
相关产品推荐

