复制构造函数 - 复制C++中的对象

copy constructor - Copying an object in C++

本文关键字:复制 对象 C++ 构造函数      更新时间:2023-10-16

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

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

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

谢谢!

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

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

但这是一个如此奇特的案例,我不会考虑它,我什至敢声称有人使用高级的东西,例如放置新应该知道他在做什么......所以省略了如果检查。

在您的特殊情况下,这似乎没问题,因为不存在可能需要深度复制的数据。但请注意,您要为成员分配两次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;
    }
}

没有提供适当的赋值运算符或复制构造函数 - 取决于实现变体,您的(赋值)或我的(构造函数委托) - 执行必要的深度复制将导致多次删除相同的数据(未定义的行为!遵循三法则(或最近的五法则),无论如何,您很可能都需要两者。然后,您可以考虑复制和交换成语成语。

最后是避免双重分配的技巧:

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