7

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

Vector v = getVector(); 

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

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

getVector 按值返回。

Vector getVector();

代码使用 C++03 标准。

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

4

4 回答 4

8

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

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

于 2012-03-31T15:49:21.897 回答
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/

于 2012-03-31T16:14:27.143 回答
1

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

要进一步添加,

情况1:

Vector v1;
Vector v(v1);

案例二:

   Vector v = getVector(); 

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

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

于 2012-03-31T16:29:12.280 回答
0

在这种情况下,复制构造函数实际上被省略了(检查this),只有默认构造函数最终被调用

编辑:

根据本杰明的回答,构造函数有时会被省略。出于某种原因,当您直接调用构造函数时,我读到了这一点。

于 2012-03-31T16:07:40.713 回答