[英]Constructor Initializer List vs Constructor Body
假设someString初始化有点复杂,因此我们编写了一个简单的成员 function stringInitialization()用于在构造函数的主体中初始化someString :
class DemoL {
private:
int someNumber;
std::string someString;
void stringInitialization() {
if (someNumber == 1) {
someString = "FIRSTSTRING";
} else if (someNumber == 2) {
someString = "SECONDSTRING";
} else {
someString = "";
}
}
public:
explicit DemoL(int rNumber) :
someNumber(rNumber) {
stringInitialization();
}
};
这样,我假设someString将在构造函数的主体之前默认初始化,只有在此之后才会通过调用stringInitialization()对其进行修改。
所以,让我们稍微修改一下代码,以便我们在构造函数初始化列表中初始化someString :
class DemoL {
private:
int someNumber;
std::string someString;
std::string stringInitialization() const {
if (someNumber == 1) {
return "FIRSTSTRING";
} else if (someNumber == 2) {
return "SECONDSTRING";
} else {
return "";
}
}
public:
explicit DemoL(int rNumber) :
someNumber(rNumber),
someString(stringInitialization()) {}
};
您能否告诉我第二种变体是否更有效和正确?
你的假设是正确的。 构造函数DemoL(int rNumber)
需要能够默认构造成员someString
,这没有问题,因为std::string
是默认可构造的。
显而易见的一点是,一个成员可能不是默认可构造的,在这种情况下,您必须对其进行初始化。
但即使是这样,如果您在之后立即更改它,默认构造它可能会浪费资源,所以第二种选择对我来说似乎更好,因为它直截了当。
但是,由于 ,不,这实际上是一个坏主意,正如评论中指出的那样。stringInitialization
按值返回,我会使用std::move
所以作为一个结论:
someNumber
是相同的someString
(“调用” std::basic_string<...>::basic_string
)然后分配它(调用std::basic_string<...>::operator=
)stringInitialization
的调用返回(调用basic_string<...>::basic_string(const char*)
)时,第二个代码从字符串文字构造返回的std::string
值,然后复制构造someString
(调用basic_string<...>::basic_string(basic_string&&)
); 实际上发生复制省略是因为stringInitialization
返回一个右值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.