一位同事正在清理几个图书馆。为此,他一直在阅读C++ 的 API 设计,其中谈到了在 C++ 类中显式启用或禁用复制。这与 Sutter 和 Alexandrescu 在他们的C++ 编码标准中所说的相同。
他同意人们应该遵循这个建议,但是这两本书似乎都没有说什么是指导何时启用或禁用的指导原则。
任何一种方式的指导?谢谢!
一位同事正在清理几个图书馆。为此,他一直在阅读C++ 的 API 设计,其中谈到了在 C++ 类中显式启用或禁用复制。这与 Sutter 和 Alexandrescu 在他们的C++ 编码标准中所说的相同。
他同意人们应该遵循这个建议,但是这两本书似乎都没有说什么是指导何时启用或禁用的指导原则。
任何一种方式的指导?谢谢!
这取决于类在应用程序中扮演的角色。除非类代表一个值,其中身份不重要,否则您应该禁止复制和分配。同样,如果类是多态的。作为一般规则,如果您要动态分配类类型的对象,则它不应该是可复制的。相反,如果类是可复制的,则不应动态分配它的实例。(但也有一些例外,动态分配并避免复制大对象的情况并不少见,即使在语义上存在争议。)
如果您正在设计一个低级库,则选择不太明确。类似的东西std::vector
可以在应用程序中扮演许多角色;在大多数情况下,复制是不合适的,但禁止复制会使它在少数合适的地方无法使用。
不可复制的类应该是例外,而不是规则。当且仅当您在复制时不能保留值语义时,您的类应该是不可复制的——例如,命名互斥体、唯一所有权指针。否则,您的课程应该是可复制的。许多 C++ 库依赖于可复制性,尤其是 C++0x 之前的库,它们不能移动。
与 DeadMG 不同,我相信大多数类应该是不可复制的。
以下是 Stroustrup 在他的《C++ 的设计与演变》一书中所写的:
“我个人认为很遗憾,默认情况下定义了复制操作,并且我禁止复制我的许多类的对象”
我认为您应该尝试编写尽可能少的代码,以使该类完成应做的事情。如果没有人试图复制该类并且它不会在不久的将来被复制,那么不要添加诸如复制构造函数或赋值运算符之类的东西。只需使课程不可复制。
当有一天你真的想要复制类时,然后添加诸如复制构造函数之类的东西。但在此之前,让类不可复制意味着要测试和维护的代码更少。
我真诚地认为应该自动提供复制语义,或者根本不提供。
但是,编写糟糕的库有时可能会受益于手动复制构造函数。
请注意,C++ 中的情况与 C++0x 中的情况非常不同(因为标准库通常需要复制语义!),我的建议几乎总是适用的。