类设计-在C++类中显式启用/禁用复制的指导

class design - Guidance for when to explicitly enable/disable copying in C++ classes?

本文关键字:复制 启用 C++      更新时间:2023-10-16

一位同事正在清理几个库。在这样做的过程中,他一直在阅读API C++设计,其中谈到了在C++类中显式启用或禁用复制。这与Sutter和Alexandrescu在C++编码标准中所说的相同。

他同意人们应该遵循这一建议,但这两本书似乎都没有说明什么是指导原则,可以决定何时启用或禁用。

有这样或那样的指导吗?谢谢

这取决于类在应用程序中扮演的角色。除非类表示一个值,在身份不重要的情况下,应该禁止复制和分配。类似地,如果类是多态的。作为一般来说,如果您正在分配类类型的对象动态地,它不应该是可复制的。反过来,如果类可复制的,不应该动态分配它的实例。(但是也有一些例外,动态分配和避免复制大对象,即使语义上有相反的争论。)

如果您正在设计一个低级库,那么选择就不那么明确了。像std::vector这样的东西可以在应用程序中扮演许多角色;在里面大多数情况下,复制是不合适的,但禁止复制会在少数合适的地方使其无法使用。

不可复制的类应该是例外,而不是规则。当并且仅当您在复制时不能保留值语义时,您的类应该是不可复制的——例如,命名互斥对象、唯一所有权指针。否则,你的类应该是可复制的。许多C++库依赖于可复制性,尤其是在C++0x之前,它们不能移动。

与DeadMG相反,我认为大多数类应该是不可复制的。

以下是斯特劳斯特鲁普在《C++的设计与进化》一书中所写的内容:

"我个人认为复制操作是默认定义的,这很不幸,我禁止复制我的许多类的对象"

我认为你应该尽量少写代码,让类做它应该做的事情。如果没有人试图复制类,而且它在不久的将来不会被复制,那么不要添加复制构造函数或赋值运算符之类的东西。只需使该类不可复制即可。

当有一天你真的想复制类时,添加一些东西,比如复制构造函数。但在此之前,类不可复制意味着要测试和维护的代码更少。

我真诚地认为复制语义应该自动提供,或者根本不提供。

然而,写得不好的库有时可能会从手动复制构造函数中受益。

请注意,C++中的情况与C++中的非常不同(因为标准库通常需要复制语义!),我的建议几乎总是适用于C++0x。