在 C++ 中复制一个对象

Copying an object in C++

我想知道相对于复制单个元素,以下列方式复制对象是否可以接受。

#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 是自动生成的,因此无法更新 class 中任何新引入的成员。当然,我可以提供一个成员函数来更新新成员,但我想探索这个选项。

代码没问题,但是方法对吗?

谢谢!

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

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

但这是一个如此奇特的案例,我不会考虑它,我什至敢于声称使用诸如 placement new 之类的高级东西的人应该知道他在做什么......所以省略 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 (or more recently, rule of five), you most probably will need both anyway. You might consider the copy and swap idiom成语然后。

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

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

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