C ++样式的构造函数调用

时间:2017-01-27 10:19:49

标签: c++ constructor initialization language-lawyer

我有一个名为Thing的对象,其构造函数采用int。

此代码按预期工作:

Thing thing(5);

然而,偶然的我写了以下内容:

Thing thing = Thing(5); // note: no 'new'

得到错误no matching constructor for initialization of 'Thing'。后一个代码的实际含义是什么?我知道如果我在那里抛出一个new意味着什么,但没有新的,这是什么意思?

2 个答案:

答案 0 :(得分:10)

Thing thing = Thing(5);

需要定义(非explicit)副本(或移动) - 构造函数:

Thing(const Thing &);

(即使出于优化原因没有调用它)。

答案 1 :(得分:9)

Thing thing(5);direct initliazationthing由apporiate构造函数(即Thing::Thing(int))直接构建。

Thing thing = Thing(5);copy initialization,这与直接初始化不完全相同。但是对于这种情况,从C ++ 17开始,它将直接调用Thing::Thing(int)来构造对象,然后它与直接初始化具有相同的效果。

  

首先,如果T是一个类类型,并且初始化程序是一个prvalue表达式,其cv-unqualified类型与T是同一个类,则初始化程序表达式本身,而不是从它实现的临时表达式,用于初始化目标对象:请参阅copy elision

在C ++ 17之前,第二种情况(即复制初始化)要求复制/移动构造函数是可访问和非显式的;如果是这种情况并且您使用的编译器不支持C ++ 17,则会导致错误。

  

如果T是类类型且other类型的cv-nonqualified版本是T或从T派生的类,则非显式构造函数检查T,并通过重载决策选择最佳匹配。然后调用构造函数来初始化对象。

请注意,从C ++ 17开始,代码编译正常。根据{{​​3}}的规则,对于这种情况,复制/移动构造函数不需要是可访问的explicit

  

在下列情况下,编制者需要省略   类对象的复制和移动构造函数,即使复制/移动也是如此   构造函数和析构函数具有可观察到的副作用:

     
      
  • 在初始化中,如果初始化表达式是prvalue,并且源类型的cv-nonqualified版本与   目的地的类,初始化表达式用于   初始化目标对象:

    T x = T(T(T())); // only one call to default constructor of T, to initialize x
    
  •