我有一个可能包含许多顶点的 Shape 类,并且我正在考虑将复制构造函数/复制分配设为私有,以防止意外不必要地复制我的重量级类(例如,通过值而不是通过引用传递)。
要制作 Shape 的副本,必须故意调用“克隆”或“复制”方法。
这是好习惯吗?我想知道为什么 STL 容器不使用这种方法,因为我很少想按值传递它们。
我有一个可能包含许多顶点的 Shape 类,并且我正在考虑将复制构造函数/复制分配设为私有,以防止意外不必要地复制我的重量级类(例如,通过值而不是通过引用传递)。
要制作 Shape 的副本,必须故意调用“克隆”或“复制”方法。
这是好习惯吗?我想知道为什么 STL 容器不使用这种方法,因为我很少想按值传递它们。
限制您的用户并不总是一个好主意。仅仅记录复制可能很昂贵就足够了。如果用户真的想要复制,那么通过提供复制构造函数来使用 C++ 的本机语法是一种更简洁的方法。
因此,我认为真正的答案取决于上下文。也许您正在编写的真实类(而不是想象中的 Shape)不应该被复制,也许它应该被复制。但作为一种通用方法,我当然不能说应该通过强制用户使用显式方法调用来阻止用户复制大对象。
恕我直言,是否提供复制构造函数和赋值运算符更多地取决于您的类建模的内容,而不是复制的成本。
如果您的类表示values,也就是说,如果传递一个对象或对象的副本没有区别,那么提供它们(并提供相等运算符)
如果您的班级不是,也就是说,如果您认为该班级的对象具有身份和状态(也有人说实体),请不要。如果副本有意义,请为其提供克隆或副本成员。
有时有些类你不能轻易分类。容器在那个位置。将它们视为实体并仅通过引用传递它们并具有特殊操作以在需要时进行复制是有意义的。您也可以将它们简单地视为值的聚合,因此复制是有意义的。STL 是围绕值类型设计的。由于一切都是价值,因此容器是有意义的。这允许类似map<int, list<> >
有用的东西。(请记住,您不能将不可复制的类放入 STL 容器中)。
通常,您不会因为类很重而使类不可复制(您已经展示了一个很好的示例 STL)。
当它们连接到某些不可复制的资源(如套接字、文件、锁)或它们根本不被设计为可复制时(例如,具有一些难以深度复制的内部结构),您使它们不可复制。
但是,在您的情况下,您的对象是可复制的,因此请保留它。
关于clone()
——它被用作多态复制构造函数——它有不同的含义和不同的用法。
大多数程序员已经意识到复制各种对象的成本,并且知道如何使用按引用传递等技术来避免复制。
请注意,STL 的向量、字符串、映射、列表等都可以被视为“重量级”对象(尤其是像具有 10,000 个元素的向量!)。这些类都仍然提供复制构造函数和赋值运算符,因此如果您知道自己在做什么(例如制作 std::list 向量),则可以在必要时复制它们。
因此,如果它有用,无论如何都要提供它们,但一定要记录它们是昂贵的操作。
根据你的需要...
如果您想确保副本不会错误地发生,并且制作副本会导致严重的瓶颈或根本没有意义,那么这是一个很好的做法。编译错误比性能调查要好。
如果您不确定您的课程将如何使用,并且不确定这是否是一个好主意,那么这不是一个好习惯。大多数时候,您不会以这种方式限制您的课程。