提问人:F.M 提问时间:2/17/2018 最后编辑:noelicusF.M 更新时间:2/17/2018 访问量:1958
如何在类包含指针时创建复制构造函数
how to create copy constructor when the class contains a pointer
问:
我对复制构造函数概念有疑问。我写了一个这样的例子:
struct f1
{
string x;
string y;
f1();
~f1();
};
struct f2
{
int a;
string b;
f1 *ff;
f2();
~f2();
};
class myclass{
f2 *obj;
}
我发现结构 f2 应该有一个复制构造函数,因为该类包含指向分配内存的指针。但我不知道我应该如何创建它。
答:
0赞
user9335240
2/17/2018
#1
您有很多选择:
主要二:
只需复制指针(浅层复制),只是不写构造函数,它将是隐式的,或者你可以写(在 ).
struct f2
f2(const f2 &original): f1(original.f1), a(original.a), b(original.b) { }
警告:这不会复制成员变量的值。它只会复制引用,这使得两个 s 都引用同一个对象。
f1
f2.f1
f1
f2 a; ... f2 b(a); // Invokes the "copy" constructor a.f1->x = "Something here"; std::cout << b.f1->x; // Will print "Something here"
创建一个深层副本,调用 的复制构造函数,并通过将新创建的副本写入
f1
this->f1
struct f2
f2(const f2 &original): f1(new f1(*original.f1)), a(original.a), b(original.b) { }
同样,正如一位评论者所建议的那样,您还必须进行复制分配,因为您创建了一个复制构造函数(例如,除非您的对象是不可变的)
f2 &operator=(const f2 &other) { if (this == &other) return; // If "self-assignment" just return. if (f1) { delete f1; } // Deletes the old one if any. // The advisable alternative is to use // a smart pointer f1 = new f1(*other.f1); a = other.a; b = other.b; return *this; }
无论如何,您应该考虑使用智能指针:、 和 ,因为原始指针可能会导致很多错误。但是智能指针会为您(部分)管理内存,让您有更多机会思考您的逻辑。一些现代C++程序员说,你不应该很少使用,智能指针就可以了unique_ptr
shared_ptr
weak_ptr
delete
评论
0赞
john
2/17/2018
不能真的同意这个答案。建议 1 不起作用,因为 f1 是动态分配的。同样在建议 2 中,赋值运算符的实现在赋值给自己的情况下被窃听。
0赞
user9335240
2/17/2018
@john 将作业固定给自己,谢谢。但是为什么建议1不起作用?,我认为它会做一个“浅拷贝”,只是复制参考。(除非他需要“深度副本”)。
0赞
user9335240
2/17/2018
@john 尝试改进答案,您现在可以检查
1赞
john
2/18/2018
因为一旦复制了指针,并且两个对象具有相同的指针,就无法知道何时删除指针。如果析构函数确实删除了指针,则您将删除同一指针两次,如果没有,则存在内存泄漏。
0赞
user9335240
2/18/2018
@john 这就是为什么建议他使用智能指针,这种“共享原始指针”非常容易出错,但他“可能”有一个项目要求,例如,它由其他父对象管理,例如包含所有这些对象的组的文档模型,“拥有”所有这些对象。但是使用智能指针或不变性/复制可能是一个更好的主意。f1
-2赞
Wulf0x67E7
2/17/2018
#2
它几乎是一个普通的构造函数,它以自己类型的实例作为参数
f2(const f2& other):a(other.a),b(other.b),ff(new f1()){
memcpy(ff,other.ff,sizeof(f1));//makes copy of ff
}
评论
2赞
bolov
2/17/2018
你不能对一个不可复制的对象做任何操作,你也无法对一个简单复制的对象执行此操作。你的代码非常非常错误。strcpy
std::string
memcpy
0赞
Wulf0x67E7
2/17/2018
好的,固定了字符串复制。不知道 std::string 的赋值已经是深拷贝了。我并不担心深度复制 f1,因为问题只是为 f2 制作一个复制构造函数。
0赞
Wulf0x67E7
2/17/2018
只是ff(new f1(*other.ff))然后?我想避免只使用隐式复制构造函数,当问题也与它们有关时。
评论
std::shared_ptr
并使用零规则。f2