为什么不允许复制构造函数和赋值运算符?

时间:2010-08-06 08:30:55

标签: c++

#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)    \
   TypeName(const TypeName&);                           \
   void operator=(const TypeName&)

我正在阅读谷歌的开源代码。 为什么不允许复制构造函数和赋值运算符?

3 个答案:

答案 0 :(得分:12)

防止复制或分配类的实例。大多数课程不允许复制。例如,考虑一个BankAccount类 - 如果您正在为银行编写软件,如果您创建帐户副本然后将信用和借记应用于这些不同的副本,他们将不会太高兴。

答案 1 :(得分:7)

复制构造函数和复制赋值运算符的问题在于,如果没有显式声明,编译器会自动生成实现。

这很容易造成意外问题。如果一个类有一个非平凡的析构函数,它几乎总是需要为复制构造函数和复制赋值运算符提供自己的实现(这是Law of the Big Three),因为默认的编译器生成的实现通常会执行错了。

违反三巨头法则经常会导致错误,例如数据成员的双重释放和内存损坏。这种错误的出现并不少见,因为班级的作者从不打算考虑复制行为,因为消费者很容易无意中复制对象。

除非该类的作者实际上已经考虑过如何正确复制该类的实例(或者除非该类有一个简单的析构函数),否则最好明确禁止复制以避免潜在的问题。然后可以推迟实现可复制性,直到实际需要它为止。

答案 2 :(得分:1)

如果您的类型包含指针或引用成员,或者它没有语义意义来复制它(例如,它有一个必须在析构函数中释放的资源句柄),那么最好禁用复制构造函数和赋值运营商。在C ++ 0x中(例如,在-std = c ++ 0x模式下的g ++ 4.4或更高版本中),您可以声明它们已被删除。在较旧的编译器中,您只需将它们声明为私有且未实现。