题目:
In which of the following scenarios is a Copy Constructor called or invoked?
A. When no conversion function exists for converting the class object to another class object
B. When an existing object is assigned an object of its own class
C. When a function receives as an argument, an object of the class, by value
D. When a function returns an object of the class by value
E. When creating an object and initializing it with an object of its own class
思路:
答案:CDE
拷贝构造函数在以下情况下被调用:
Class A{};
1、类对象以传值的形式作为函数参数,如 void func(A a);
2、函数返回值为类对象的值,如 A func();
3、创建某个类并初始化它,如 Class B; Class A(B);
扩展:
1、什么是拷贝构造函数?
对于一个类X,如果一个构造函数的第一个参数是下列之一:
a) X&
b) const X&
c) volatile X&
d) const volatile X&
且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数.
X::X(const X&); //是拷贝构造函数 X::X(X&, int=); //是拷贝构造函数
2、一个类中可以存在多于一个的拷贝构造函数吗?
类中可以存在超过一个拷贝构造函数
class X { public: X(const X&); X(X&); // OK };
注意,如果一个类中只存在一个参数为X&的拷贝构造函数,那么就不能使用const X或volatile X的对象实行拷贝初始化.
class X { public: X(); X(X&); }; const X cx; X x = cx; // error
如果一个类中没有定义拷贝构造函数,那么编译器会自动产生一个默认的拷贝构造函数.
这个默认的参数可能为X::X(const X&)或X::X(X&),由编译器根据上下文决定选择哪一个.
默认拷贝构造函数的行为如下:
默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造.
拷贝构造函数对类中每一个数据成员执行成员拷贝(memberwise Copy)的动作.
a)如果数据成员为某一个类的实例,那么调用此类的拷贝构造函数.
b)如果数据成员是一个数组,对数组的每一个执行按位拷贝.
c)如果数据成员是一个数量,如int,double,那么调用系统内建的赋值运算符对其进行赋值.
3、拷贝构造函数可以由成员函数模板生成吗?
拷贝构造函数不能由成员函数模版生成.
struct X { template<typename T> X( const T& ); // NOT copy ctor, T can't be X template<typename T> operator=( const T& ); // NOT copy ass't, T can't be X };
原因很简单, 成员函数模版并不改变语言的规则,而语言的规则说,如果程序需要一个拷贝构造函数而你没有声明它,那么编译器会为你自动生成一个. 所以成员函数模版并不会阻止编译器生成拷贝构造函数。
赋值运算符重载也遵循同样的规则.(参见Effective C++ 3edition, Item45)