通常使重量级课程不可复制是一种好习惯吗?

时间:2010-03-19 15:58:44

标签: c++ noncopyable

我有一个包含潜在许多顶点的Shape类,我正在考虑将copy-constructor / copy-assignment设为私有,以防止意外不必要地复制我的重量级类(例如,通过值而不是通过引用传递)。

要制作Shape的副本,必须故意调用“克隆”或“复制”方法。

这是好习惯吗?我想知道为什么STL容器不使用这种方法,因为我很少想通过值传递它们。

5 个答案:

答案 0 :(得分:7)

限制用户并不总是一个好主意。只记录复制可能很昂贵就足够了。如果用户确实想要复制,那么通过提供复制构造函数来使用C ++的本机语法是一种更清晰的方法。

因此,我认为真正的答案取决于背景。也许不应该复制你正在写的真正的类(不是想象的形状),也许它应该被复制。但作为一般方法,我当然不能说人们应该阻止用户通过强制他们使用显式方法调用来复制大对象。

答案 1 :(得分:4)

恕我直言,提供复制构造函数和赋值运算符或不依赖于您的类建模而不是复制成本。

如果你的类代表,那么如果传递对象或对象的副本没有区别,那么提供它们(并提供相等运算符)

如果您的班级不是,那就是如果您认为班级的对象具有身份和状态(也可以说是实体),请不要。如果副本有意义,请为其提供克隆或复制成员。

有时您无法轻易分类。容器处于那个位置。将它们视为实体并仅通过引用传递它们并在需要时进行特殊操作来制作副本是很有意义的。您也可以将它们简单地视为值的集合,因此复制是有意义的。 STL是围绕价值类型设计的。因为一切都是价值,所以容器是有意义的。这允许像map<int, list<> >这样有用的东西。 (请记住,您不能将nocopyable类放在STL容器中。)

答案 2 :(得分:4)

通常,你不会因为它们很重而使类不可复制(你已经展示了一个很好的例子STL)。

当它们连接到某些不可复制的资源(例如套接字,文件,锁定)或者它们不是设计以便完全复制时(例如具有一些可以使用的内部结构),它们使它们不可复制很难被深深复制。)

但是,在您的情况下,您的对象是可复制的,因此请将其保留为此。

关于clone()的小注释 - 它被用作多态复制构造函数 - 它有不同之处 意思和用法不同。

答案 3 :(得分:4)

大多数程序员已经知道复制各种对象的成本,并且知道如何使用诸如传递参考之类的技术来避免复制。

请注意,STL的矢量,字符串,地图,列表等都可以被认为是“重量级”对象(特别是像10,000个元素的矢量!)。这些类仍然提供了复制构造函数和赋值运算符,所以如果你知道你正在做什么(比如制作一个std :: vector向量),你可以在必要时复制它们。

因此,如果它有用,无论如何都要提供它们,但一定要记录它们是昂贵的操作。

答案 4 :(得分:2)

根据您的需要......

如果你想确保副本不会被错误地发生,并且制作副本会导致严重的瓶颈或者根本没有意义,那么这是一个好习惯。编译错误比性能调查更好。

如果您不确定如何使用您的课程,并且不确定这是否是一个好主意,那么这不是一个好习惯。大多数时候你不会以这种方式限制你的课程。