分配为默认初始化

tar*_*len 17 c++ constructor

假设我有一个struct(或类)动态数组,它的长度和构造函数:

struct array {
    int l;
    int* t;
    array(int length);
};

array::array(int length) {
    l=length;
    t=new int[l];
}
Run Code Online (Sandbox Code Playgroud)

我假设到目前为止所有内容都是合法的:这就是我写它的方式(尽管它可能不是唯一的方法),但是我看到了下面的代码,它似乎有点起作用:

struct array {
    int l;
    int* t = new int[l];
    array(int length);
}

array::array(int length) {
    l=length;
}
Run Code Online (Sandbox Code Playgroud)

它看起来很糟糕,所以我想知道这是出于纯粹的运气和未定义的行为,还是有一些内部规则可以使这段代码正常工作.

Bau*_*gen 29

此代码不正确.

int* t = new int[l];将在此之前发生l=length;,从而读取未初始化的变量l.成员初始值设定项在构造函数的主体运行之前处理.

array::array(int length) : l{length} {}
Run Code Online (Sandbox Code Playgroud)

相反会工作,因为l之前已声明t.

然而,"手动"这样做是一个坏主意.你应该使用std::vector.


son*_*yao 10

第二个代码段可能有未定义的行为.

数据成员按其声明的顺序初始化.对于类array,当t初始化l尚未初始化.对于具有自动和动态存储持续时间的对象,l将初始化为不确定值,然后使用l(即new int[l])导致UB.

请注意,l=length;构造函数的主体内部只是赋值; 在此之前,数据成员的初始化已经完成.

顺便说一句:使用成员初始化列表,第一个代码片段可以重写为

array::array(int length) : l(length), t(new int[l]) {
}
Run Code Online (Sandbox Code Playgroud)

  • 你为什么说"可能"?它无条件地拥有UB. (3认同)