在下面的代码中,d = a;
不会调用复制构造函数。
如何将a复制到d?或者在什么情况下我们必须重载=运算符?
#include<iostream>
using namespace std;
class code{
int id;
public:
code(){}//default constructor
code(int a){
id=a;
}
code(code & x){//copy constructor
id=x.id;
}
void display(){
cout<<id;
}
};
int main(){
code a(100);
code b(a);//copy constructor is called
code c=a;//copy constructor is called again
code d;
c=a;//copy constructor is not called this time
std::cout << "\n id of A: ";
a.display();
cout << "\n id of B: ";
b.display();
cout << "\n id of C: ";
c.display();
cout << "\n id of D: ";
d.display();
return 0;
}
如何有效地实现复制构造函数?
答案 0 :(得分:1)
根据C ++标准(12.8复制和移动类对象)
18如果类定义没有显式声明一个复制赋值运算符,则会隐式声明一个。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制赋值运算符被定义为已删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制构造函数或用户声明的析构函数,则不推荐使用后一种情况。类X的隐式声明的复制赋值运算符将具有
形式28非联合类X 的隐式定义的复制/移动赋值运算符执行其子对象的成员复制/移动分配。
在本声明中
c=a;
使用了编译器复制赋值运算符隐式定义的,因为类没有显式定义它并且它执行对象数据成员的成员副本(对于此类定义,它是数据成员int id;
)< / p>
当成员方式复制对象的子对象不满足类要求时,您需要明确定义复制赋值运算符。
答案 1 :(得分:0)
不会调用复制构造函数,因为会调用隐式定义的复制赋值运算符。它的形式为:
T& T::operator=(const T&)
答案 2 :(得分:0)
可以在初始化期间调用复制构造函数:
code d = a;
在您的代码中:
code d;
d = a;
operator=
被调用。
答案 3 :(得分:0)
如何将a复制到d?
使用复制赋值运算符。复制构造函数用于初始化,而不是赋值。
在什么情况下我们必须重载=运算符?
当您需要除递归复制每个子对象的默认行为之外的其他内容。在您的情况下,默认行为是简单地复制id
值。这也是复制构造函数的默认行为,因此您也不需要提供它。
Rule of Three是您需要提供这些运营商的良好指南。当您的类管理另一个资源的生命周期时,您通常需要它们,它在析构函数中释放。您需要非标准的复制语义,这样就不会有两个对象试图释放相同的资源。