【问题标题】:Correct way to initialize a member struct初始化成员结构的正确方法
【发布时间】:2017-05-19 00:20:50
【问题描述】:

假设我有以下代码:(请注意,我不能更改 Vec2 的声明)

图表 A

struct Vec2 {
  float x;
  float y;
};

class C {
  struct Data {
    Vec2 v1;
    Vec2 v2;
    int n = 0;
  };
  Data _data;

  C() : _data() {}
};

这似乎正确地将 Data 中的两个 Vec2 结构初始化为零值。为什么会这样? C的构造函数初始化列表中的初始化是否处理这个?

更正确的形式会像这样使用统一初始化语法吗?

图表 B

class C {
  struct Data {
    Vec2 v1{};
    Vec2 v2{};
    int n{};
  };
  Data _data;

  C() {}
};

这引出了我的第二个问题——如果 _data 的构造函数不带参数,它是否需要进入构造函数的初始化列表?或者编译器是否期望隐式处理初始化?我注意到,当使用展示 A 中的声明,但在构造函数中省略了初始化列表时,在 VC++ 编译器上,似乎确实如此,但是,在 Clang 上,数据似乎未初始化。

【问题讨论】:

  • 我不确定标准将如何指定此行为,但是我注意到您尝试初始化成员结构的一件事是您的结构没有声明的默认构造函数。
  • 与现代 C++ 统一初始化程序相比,构造函数是首选方法吗?
  • 我觉得还是看源码内部的实际需要和要求;两者都有效。

标签: c++ c++11 initialization c++14


【解决方案1】:

不确定这是否会有所帮助,但如果您要将默认构造函数添加到结构中,那么您应该能够执行以下操作:

struct Vec2 {
  float x;
  float y;
  Vec2() : x(0.0f), y(0.0f) {}
};

class C {
  struct Data {
    Vec2 v1;
    Vec2 v2;
    int n;

    Data() : v1( Vec2() ), v2( Vec2() ), n(0) {}
  };
  Data _data;

  C() : _data( Data() ) {}
};

编辑

OP提到他不能间接修改Vec2,可以做的是:

#include "Vec2"

class MyVec2 : public Vec2 {
public:
   MyVec2() : x(0), y(0) {}
};

那么您应该能够使用您定义的Vec2 版本及其构造函数。其余代码将保持不变,但这可能会导致问题,因为基类没有自己的default constructor

【讨论】:

  • 这可行,但由于其他原因我无法修改 Vec2。我想我可以在 Data 的构造函数中进行 memset 或者说“v1 = {0};”
  • @unixunited 哦,我明白了,如果你不能修改Vec2,那么也许你可以做的是从Vec2 继承并定义你自己的类,它是一个派生类,你可以在其中创建自己的构造函数。
猜你喜欢
  • 2018-11-24
  • 2011-08-20
  • 1970-01-01
  • 1970-01-01
  • 2022-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多