构造函数定义 C++ 语法

Constructor Definition C++ syntax

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

class Fruit {
  private:
    int price;

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

VS

class Fruit {
  private:
    int price;

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

第一次看到继承案例。

据我所知,这不是一个重复的问题。如果您找到一个,请随时关闭此问题。

第一个使用 initialization list,而另一个不使用,并将 x 分配给构造函数体内的数据成员 price

我们通常prefer to use initialization lists,并使构造函数的主体尽可能简单。

第一个用x初始化price,第二个用默认值初始化price(默认构造它;如果是int变量,使用未定义的值初始化)然后将 x 复制到 price.

换句话说,第一个几乎相当于

int price = x;

其中第二个几乎等同于

int price;

price = x;

int 变量的情况下(也考虑编译器的优化)我想没有有效的区别。

但是当price是一个复杂的对象,建造成本很高时,就会有很大的不同。

为了更好地解释彼得,"It's not construction cost that makes the difference between the two for complex objects. It is a question of whether reassigning after default initialisation is more costly than initialising in one step. Practically, the two stage process is often more expensive (by various measures) than direct initialisation, since it can be necessary to clean up the default setting in order to change the value. There are also concerns of exception safety - what if reassignment or construction throws an exception."

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

另见 Zereges 的回答,指出第一个方法是唯一可用于为常量成员赋值的事实。

确实不会写

int const  price;

price = x;  // error: price is const

第二个在创建 Fruit 时不会用 x 初始化 price,因此默认构造它。就像你写的一样:

class Fruit{
private :
    int price

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

为了效率,最好用你想赋给它的值来初始化。

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

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

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;
    }
};