C ++ Copy Constructor和重载=运算符的情况

时间:2015-03-06 14:21:53

标签: c++ g++

在下面的代码中,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;
}

如何有效地实现复制构造函数?

4 个答案:

答案 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是您需要提供这些运营商的良好指南。当您的类管理另一个资源的生命周期时,您通常需要它们,它在析构函数中释放。您需要非标准的复制语义,这样就不会有两个对象试图释放相同的资源。