构造函数定义C ++语法

时间:2018-11-10 22:26:41

标签: c++ oop c++11 ctor-initializer

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

class Fruit {
  private:
    int price;

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

VS

class Fruit {
  private:
    int price;

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

在继承的情况下,我见过的第一个。

据我所知,这不是重复的问题。如果您发现可以随时关闭此问题。

4 个答案:

答案 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
    }    
}

出于有效性考虑,最好使用要为其分配的值进行初始化。