我想知道是否可以通过以下方式复制对象,而不是复制单个元素。
#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是自动生成的,因此无法更新类中任何新引入的成员。我可以提供一个成员函数来更新新成员,当然,但想要探索这个选项。
代码工作正常,但方法是否正确?
谢谢!
答案 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)
{ }