说我有一个struct
(或类),它带有一个动态数组,其长度和一个构造函数:
struct array {
int l;
int* t;
array(int length);
};
array::array(int length) {
l=length;
t=new int[l];
}
我认为到目前为止,所有事情都是合法的:这就是我的编写方式(尽管它可能不是唯一的处理方式),但是我看到了以下代码,这似乎有些用:
struct array {
int l;
int* t = new int[l];
array(int length);
}
array::array(int length) {
l=length;
}
它看起来很糟糕,所以我想知道这是不是出于运气和未定义的行为,还是有一些内部规则可以使此代码正常工作。
答案 0 :(得分:29)
此代码不正确。
int* t = new int[l];
将在l=length;
之前发生,从而读取未初始化的变量l
。成员初始化程序在构造器主体运行之前 处理。
array::array(int length) : l{length} {}
相反会起作用,因为l
是在t
之前声明的。
但是,首先“手工”执行此操作不是一个好主意。您应该使用std::vector
。
答案 1 :(得分:10)
第二个代码段可能具有未定义的行为。
数据成员按照它们声明的顺序进行初始化。对于类array
,当初始化t
时l
尚未初始化。对于具有自动和动态存储持续时间l
的对象,将其初始化为不确定的值,然后使用l
(即new int[l]
)会导致UB。
请注意,构造函数主体中的l=length;
只是赋值;在此之前,数据成员的初始化已经完成。
顺便说一句:使用成员初始化程序列表,第一个代码段应重写为
array::array(int length) : l(length), t(new int[l]) {
}