在这里调用哪个构造函数?

时间:2012-03-31 15:45:59

标签: c++ c++03

在这个代码片段中,实际调用了哪个构造函数?

Vector v = getVector(); 

Vector具有复制构造函数,默认构造函数和赋值运算符:

class Vector {
public:
    ...
    Vector();
    Vector(const Vector& other);
    Vector& operator=(const Vector& other);
};

getVector按值返回。

Vector getVector();

代码使用C ++ 03标准。

代码片段看起来应该调用默认构造函数然后调用赋值运算符,但我怀疑这个声明是使用复制构造函数的另一种形式。哪个是对的?

4 个答案:

答案 0 :(得分:8)

当初始化中出现=时,它会调用复制构造函数。一般形式与直接调用复制构造函数不完全相同。在语句T a = expr;中,如果expr的类型为T,则会调用复制构造函数。如果expr不是T类型,那么首先进行隐式转换,如果可能的话,然后使用它作为参数调用复制构造函数。如果无法进行隐式转换,则代码格式不正确。

根据getVector()的结构,可以优化副本,并且在函数内创建的对象与存储在v中的物理对象相同。

答案 1 :(得分:2)

假设您在所显示的代码之外没有做过任何病态的事情,您的声明是复制初始化,并且该规则的第二部分适用:

13.3.1.3 Initialization by constructor [over.match.ctor]

1 When objects of class type are direct-initialized (8.5), or copy-initialized from an 
  expression of the same or a derived class type (8.5), overload resolution selects the
  constructor. For direct-initialization, the candidate functions are all the constructors
  of the class of the object being initialized. For copy-initialization, the candidate 
  functions are all the converting constructors (12.3.1) of that class. The argument 
  list is the expression-list within the parentheses of the initializer.

对于一个简单的测试用例,请参阅Eli Bendersky的帖子,在这里:http://eli.thegreenplace.net/2003/07/23/variable-initialization-in-c/

答案 2 :(得分:1)

永远记住规则:
每当一个对象被创建并在同一个语句中给出一些值时,它就从不一个赋值。

进一步添加,

案例1:

Vector v1;
Vector v(v1);

案例2:

   Vector v = getVector(); 

在上述两种格式中,案例1 直接初始化,而案例2 称为复制初始化

复制初始化如何工作?
复制初始化构造隐式转换序列:它尝试将getVector()的返回值转换为类型为Vector的对象。然后它可以将创建的对象复制到正在初始化的对象中,因此它需要一个可访问的复制构造函数。

答案 3 :(得分:0)

在这种情况下,复制构造函数实际上已被删除(检查this)并且只是默认构造函数最终被调用

修改

根据Benjamin的回答,构造函数有时仅被省略。出于某种原因,我在你直接调用构造函数时读到了它。