简体   繁体   English

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

[英]Why copy constructor and assignment operator are disallowed?

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

I'm, reading open source code from google. 我是,从谷歌阅读开源代码。 Why copy constructor and assignment operator are disallowed? 为什么不允许复制构造函数和赋值运算符?

To prevent instances of the class being copied or assigned. 防止复制或分配类的实例。 Most classes should not allow copying. 大多数课程不允许复制。 Consider for example a BankAccount class - if you are writing software for a bank, they will not be too happy if you create copies of accounts and then apply credits and debits to those different copies. 考虑一下例如BankAccount类 - 如果您正在为银行编写软件,如果您创建帐户副本然后将信用和借记应用于这些不同的副本,他们将不会太高兴。

The problem with the copy constructor and copy-assignment operator is that the compiler generates implementations automatically if they're not explicitly declared. 复制构造函数和复制赋值运算符的问题在于,如果没有显式声明,编译器会自动生成实现。

This can easily cause unintended problems. 这很容易造成意外问题。 If a class has a non-trivial destructor, it almost always needs to provide its own implementations for the copy constructor and copy-assignment operator too (this is the Law of the Big Three ) since the default compiler-generated ones usually will do the wrong thing. 如果一个类有一个非平凡的析构函数,它几乎总是需要为复制构造函数和复制赋值运算符提供自己的实现(这是三巨头法则 ),因为默认的编译器生成的通常会执行错了。

Violating the Law of the Big Three often leads to errors such as double-frees of data members and memory corruption. 违反三巨头法则经常会导致错误,例如数据成员的双重释放和内存损坏。 It's not uncommon for these sort of errors to arise because the author of the class never bothered to think about copy behavior and because it's easy for consumers to copy objects unintentionally. 这种错误的出现并不少见,因为班级的作者从不打算考虑复制行为,因为消费者很容易无意中复制对象。

Unless the author of the class has actually thought about how to properly copy instances of that class (or unless the class has a trivial destructor), then it's better to explicitly disallow copying to avoid potential problems. 除非该类的作者实际上已经考虑过如何正确地复制该类的实例(或者除非该类有一个简单的析构函数),否则最好明确禁止复制以避免潜在的问题。 Implementing copyability could then be deferred until there's an actual need for it. 然后可以推迟实现可复制性,直到实际需要它为止。

If your type contains pointer or reference members, or it makes no semantic sense for it to be copied (eg it has a resource handle that must be freed in the destructor) then it is good practice to disable the copy constructor and assignment operator. 如果您的类型包含指针或引用成员,或者它没有语义意义来复制它(例如,它有一个必须在析构函数中释放的资源句柄),那么最好禁用复制构造函数和赋值运算符。 In C++0x (eg in g++ 4.4 or later in -std=c++0x mode) you can declare them deleted. 在C ++ 0x中(例如,在-cd = c ++ 0x模式下的g ++ 4.4或更高版本中),您可以声明它们已被删除。 In older compilers you just declare them private and unimplemented. 在较旧的编译器中,您只需将它们声明为私有且未实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM