用C ++复制对象

时间:2016-07-15 05:35:17

标签: c++ copy-constructor

我想知道是否可以通过以下方式复制对象,而不是复制单个元素。

#include <iostream>
using namespace std;

class abc{
public:
    abc(int a = 10, int b = 5);
    abc(const abc &obj, int b = 10);

    int ret_x() { return x; }
    int ret_y() { return y; }
private:
    int x;
    int y;
};

abc::abc(int a, int b)
    : x(a),
    y(b)
{
}

abc::abc(const abc &obj, int b)
{
    if (this != &obj) {
        *this = obj;    -----> Copying the object
    }
    y = b;
}

int main()
{
    abc a1;
    cout << "A1 values: " << a1.ret_x() << "\t" << a1.ret_y() << endl;
    abc a2(a1, 20);
    cout << "A2 values: " << a2.ret_x() << "\t" << a2.ret_y() << endl;

    return 0;
}

编辑:

用例:

问题是对象a1是自动生成的,因此无法更新类中任何新引入的成员。我可以提供一个成员函数来更新新成员,当然,但想要探索这个选项。

代码工作正常,但方法是否正确?

谢谢!

1 个答案:

答案 0 :(得分:2)

正如克里斯在评论中已经指出的那样,你正在创建一个全新的对象。您希望如何将this传递给构造函数?嗯,实际上,您可以通过新的位置:

abc a;
abc* b = new(&a)abc(a);

但这是一个如此异乎寻常的案例,我不会考虑它,我甚至敢于声称有人使用先进的东西,如安置新的应该知道他在做什么......所以省略if-check。

在您的特殊情况下,似乎没问题,因为不存在可能需要深度复制的数据。但请注意,您要分配成员b两次。对于int来说并不是很关键,但是对于执行深层复制的较大对象(std :: string,std :: vector,...),这会越来越有问题。

但是,对于C ++ 11,我更喜欢构造函数委派:

abc::abc(const abc& obj, int b)
    : abc(obj) // copying here
{
    y = b;
}

然而,这并没有解决双重赋值问题。说实话,这可能并不总是一个真正的问题,在许多情况下,编译器可能会优化第一个任务(特别是在我们示例的int情况下)。但是对于更复杂的数据类型(可能已经是std :: string),依靠编译器检测过时的赋值我感觉不舒服......

请注意,如果您在内部管理资源,可能会遇到麻烦:

struct abc
{
    int* array;
    abc() : array(new int[7]) { }
    ~abc()
    {
        delete[] array;
    }
}

不提供适当的赋值运算符或复制构造函数 - 取决于实现变量,您的(赋值)或我的(构造函数委托) - 执行必要的深层复制将导致多次删除相同的数据(未定义的行为!)。在rule of three(或最近,rule of five)之后,您最有可能需要两者。您可以考虑copy and swap idiom成语。

最后一个避免双重赋值的技巧:

abc(abc const& other)
    : abc(other, other.y)
{ }

abc(abc const& other, int y)
    : x(other.x), y(y)
{ }