根据Google style guidelines,“很少有类需要复制。大多数都不应该有复制构造函数或赋值运算符。”
他们建议您使类不可复制(即,不给它复制构造函数或赋值运算符),而是建议在大多数情况下通过引用或指针传递,或者使用无法隐式调用的clone()方法。
但是,我听到了一些反对这一点的论点:
遵循本指南有哪些正面/负面影响?是否有任何标准的“经验法则”使类不可复制?创建新类时我应该考虑什么?
答案 0 :(得分:6)
我的建议有两个问题:
它不适用于现代C ++,忽略移动构造函数/赋值运算符,因此假定按值获取对象(以前会复制过)通常效率低下。
它并不信任程序员做正确的事情并适当地设计他们的代码。相反,它会限制程序员,直到他们被迫违反规则。
您的班级是否应该是可复制的,可移动的,两者都是,或者两者都不应该是基于班级本身使用的设计决定。例如,std::unique_ptr
是一个只能移动的类的一个很好的例子,因为复制它会使其整个目的无效。在设计课程时,问问自己复制课程是否有意义。大多数时候答案都是肯定的。
这个建议似乎是基于这样一种信念,即程序员默认按值传递对象,当对象足够复杂时,这可能很昂贵。这不再是真的。当需要对象的副本时,你应该默认按值传递对象,并且没有理由害怕这个 - 在很多情况下,将使用移动构造函数,这几乎总是一个恒定的时间操作。
同样,选择如何传递对象是一种设计决策,应该受到许多因素的影响,例如:
这些问题应该与您编写的每种类型(参数,返回值,变量等)一起询问。您应该找到很多用于按价值传递对象的用途,这些用户不会因复制而导致性能下降。
如果您遵循良好的C ++编程实践,您的副本构造函数将是无bug的,因此不应该成为一个问题。实际上,许多类只能使用默认的复制/移动构造函数。如果一个类拥有动态分配的资源并且您正确使用智能指针,那么实现复制构造函数通常就像从指针复制对象一样简单 - 没有多大的空间来容纳错误。
当然,Google提供的建议适用于处理代码的人员,以确保整个代码库的一致性。没关系。但是,我并不建议盲目地将它全部用于现代C ++项目。