Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 构造函数定义C++;语法_C++_Oop_C++11_Ctor Initializer - Fatal编程技术网

C++ 构造函数定义C++;语法

C++ 构造函数定义C++;语法,c++,oop,c++11,ctor-initializer,C++,Oop,C++11,Ctor Initializer,这两种构造函数声明之间的区别是什么: class Fruit { private: int price; public: Fruit(int x): price(x) { } }; VS 我见过的第一个是关于继承的 据我所知,这不是一个重复的问题。如果你找到一个,请随意结束这个问题 第一个使用,而另一个不使用,并将x分配给构造函数主体内的数据成员price 我们通常使用,并保持构造函数体尽可能简单。第一个构造函数使用x初始化price,第二个构

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

class Fruit {
  private:
    int price;

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

我见过的第一个是关于继承的

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

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


我们通常使用,并保持构造函数体尽可能简单。

第一个构造函数使用
x
初始化
price
,第二个构造函数使用其默认值初始化
price
(默认构造它;对于
int
变量,使用未定义的值初始化它)然后在
price
中复制
x

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

int price = x;
int price;

price = x;
其中第二个几乎等于

int price = x;
int price;

price = x;
对于
int
变量(同时考虑编译器的优化),我认为没有有效的区别

但是当
价格
是一个复杂的对象,并且建设成本很高时,可能会有很大的差异


正如Peter更好地解释的那样,“对于复杂对象而言,建筑成本并不是两者之间的区别。问题在于,在默认初始化后重新分配是否比一步初始化成本更高。实际上,两个阶段的过程通常更昂贵(通过各种措施)而不是直接初始化,因为可能需要清除默认设置以更改值。还存在异常安全问题-如果重新分配或构造引发异常,该怎么办。”

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

另请参见Zereges的答案,该答案指出,第一个方法是唯一可用于为常量成员赋值的方法

你确实不会写字

int const  price;

price = x;  // error: price is const

当创建一个水果时,第二个水果不会用
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'
    }
};
另外,当类具有类型为的成员时,这些成员不是默认可构造的,这是初始化它们的方法

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

不幸的是,初始化列表的语法有点难看,不能使用中间的右值。的确是@Dai,但仍然有用!这是不对的。无法“初始化构造函数主体内的数据成员”。这是一项作业。@LightnessRaces轨道捕捉正确,更正,谢谢!可能值得注意的是,对于用户定义的类型,第二个选项调用默认构造函数,它可能不像
int price那样没有操作。哦,您刚刚添加了:)对于复杂对象,并不是构造成本决定了两者之间的差异。这是一个在默认初始化后重新分配是否比一步初始化成本更高的问题。实际上,两阶段过程通常比直接初始化更昂贵(通过各种措施),因为可能需要清除默认设置以更改值。还有一些关于异常安全的问题——如果重新分配或构造引发异常,该怎么办。@Peter——我试图解释这一点,但你的解释比我的解释清楚得多。我只是复制了它。谢谢。不过,除非您添加一个;声明后:
int价格类似地,当类类型的成员没有可访问的默认构造函数时,只能使用mem初始值设定项列表初始化该成员。