这两个构造函数声明有什么区别?
class Fruit {
private:
int price;
public:
Fruit(int x): price(x)
{
}
};
VS
class Fruit {
private:
int price;
public:
Fruit(int x)
{
price = x;
}
};
在继承的情况下,我见过的第一个。
据我所知,这不是重复的问题。如果您发现可以随时关闭此问题。
答案 0 :(得分:8)
第一个用price
初始化x
,第二个用默认值初始化price
(默认构造它;如果是int
变量,则初始化)并使用未定义的值),然后将x
复制到price
中。
换句话说,第一个几乎等于
int price = x;
其中第二个几乎等于
int price;
price = x;
在使用int
变量的情况下(还要考虑编译器的优化),我想没有有效的区别。
但是当price
是一个复杂的对象,并且建造成本很高时,可能会有很大的差异。
正如彼得更好地解释的那样,“复杂对象之间的区别不是由建设成本引起的。这是一个问题,即默认初始化后重新分配是否比第一步初始化更昂贵。实际上,两阶段过程是通常(通过各种措施)比直接初始化要昂贵,因为可能有必要清理默认设置以更改值。此外,还存在异常安全性问题-如果重新分配或构造引发异常怎么办。” >
因此,通常强烈建议使用第一种解决方案(使用正确的值初始化对象)。
另请参阅Zereges的答案,指出第一个方法是唯一可为常量成员赋值的方法。
实际上你不会写
int const price;
price = x; // error: price is const
答案 1 :(得分:6)
第一个使用initialization list,另一个不使用B = sph2cart(theta,phi,r);
并将x
分配给构造函数体内的数据成员price
。
我们通常prefer to use initialization lists,并保持构造函数的主体尽可能简单。
答案 2 :(得分:4)
要添加其他答案,第一种选择是初始化const data = {
"1": {
"id": 1,
"next_1": 2,
"next_2": 3,
"stop": false
},
"2": {
"id": 2,
"next_1": 3,
"next_2": 4,
"stop": false
},
"3": {
"id": 3,
"stop": true
},
"4": {
"id": 4,
"stop": true
}
};
function build(root, idx) {
const item = root[idx];
const result = {};
if(!item.stop) {
result[item.next_1] = build(root, item.next_1);
result[item.next_2] = build(root, item.next_2);
}
return result;
}
alert(JSON.stringify(build(data, 1)));
成员的自然方法
const
此外,当类具有无法默认构造的类型的成员时,这是初始化它们的方法
struct C
{
const int val;
C() : val(5) // Perfectly OK
{
}
C(int) // error: uninitialized const member in 'const int' [-fpermissive]
{
val = 5 // error: assignment of read-only member 'C::val'
}
};
答案 3 :(得分:3)
当创建price
并为其默认构造时,第二个不使用x
初始化Fruit
。就像您写过一样:
class Fruit{
private :
int price
public:
Fruit(int x) :
price() // default constructed
{
price = x
}
}
出于有效性考虑,最好使用要为其分配的值进行初始化。