在这个代码片段中,实际调用了哪个构造函数?
Vector v = getVector();
Vector具有复制构造函数,默认构造函数和赋值运算符:
class Vector {
public:
...
Vector();
Vector(const Vector& other);
Vector& operator=(const Vector& other);
};
getVector按值返回。
Vector getVector();
代码使用C ++ 03标准。
代码片段看起来应该调用默认构造函数然后调用赋值运算符,但我怀疑这个声明是使用复制构造函数的另一种形式。哪个是对的?
答案 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)