构造函数定义C++语法



构造函数的这两个声明之间有什么区别:

class Fruit {
private:
int price;
public:
Fruit(int x): price(x)
{
}    
};

class Fruit {
private:
int price;
public:
Fruit(int x)
{
price = x;
}
};

我见过的第一个关于继承的案例。

据我所知,这不是一个重复的问题。如果你找到一个,请随意结束这个问题。

第一个用x初始化price,第二个用默认值初始化price(默认构造;如果是int变量,则用未定义的值初始化(,然后在price中复制x

换句话说,第一个几乎等同于

int price = x;

其中第二个几乎等同于

int price;
price = x;

int变量的情况下(同时考虑编译器的优化(,我认为没有有效的区别。

但当price是一个复杂的对象,具有沉重的建设成本时,可能会有很大的差异。

为了更好地解释Peter,"对于复杂的对象来说,这两者之间的区别并不是建筑成本。问题是,默认初始化后的重新分配是否比一步初始化更昂贵。实际上,两阶段的过程通常更昂贵(从各种衡量标准来看(而不是直接初始化,因为可能需要清除默认设置才能更改值。还有对异常安全性的担忧——如果重新分配或构建抛出异常会怎样。">

因此,通常强烈建议使用第一个解决方案(使用正确的值初始化对象(。

另请参阅Zereges的回答,该回答将注意力集中在第一个方法是唯一可用于为常量成员赋值的方法这一事实上。

实际上你不会写

int const  price;
price = x;  // error: price is const

第一个使用初始化列表,而另一个不使用,并将x分配给构造函数主体内的数据成员price

我们通常更喜欢使用初始化列表,并使构造函数的主体尽可能简单。

要加上其他答案,第一个选项是初始化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'
}
};

此外,当类具有类型的成员时,这些成员不是默认可构造的,这是初始化它们的方法

struct D
{
struct not_default_constructible
{
not_default_constructible(int)
{
}
} var;
int& ref;
D(int a) : ref(a), var(5) // Legal
{
}
D(int a, char) // error: uninitialized reference member in 'int&' [-fpermissive]
{ // error: no matching function for call to 'D::not_default_constructible::not_default_constructible()'
ref = a;
}
};

当创建Fruit时,第二个不会用x初始化price,因此默认会构造它

class Fruit{
private :
int price
public:
Fruit(int x) :
price() // default constructed
{
price = x
}    
}

为了有效性,最好使用您想要分配给它的值进行初始化

最新更新