提问人:MainID 提问时间:8/6/2010 最后编辑:MainID 更新时间:8/6/2010 访问量:5275
为什么不允许复制构造函数和赋值运算符?
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&)
我正在阅读谷歌的开源代码。 为什么不允许复制构造函数和赋值运算符?
答:
12赞
anon
8/6/2010
#1
防止复制或分配类的实例。大多数类不应允许复制。以BankAccount类为例,如果你正在为一家银行编写软件,如果你创建账户的副本,然后将贷方和借方应用于这些不同的副本,他们不会太高兴。
评论
0赞
KedarX
8/6/2010
+1 .... @DumbCoder 如果您是该银行软件的编码员,那将是可能的!
0赞
MainID
8/10/2010
@Neil Butterworth:为什么不直接使用单例呢?
4赞
8/10/2010
@MainId 一个单一的账户意味着只能存在一个银行账户——银行必须拥有数千个东西。
0赞
E. Vakili
6/20/2020
说大多数类应该禁止复制是不正确的。顺便说一句,谷歌是这么认为的。
1赞
Anthony Williams
8/6/2010
#2
如果您的类型包含指针或引用成员,或者复制它没有语义意义(例如,它有一个必须在析构函数中释放的资源句柄),那么最好禁用复制构造函数和赋值运算符。在 C++0x 中(例如,在 g++ 4.4 或更高版本的 -std=c++0x 模式下),您可以声明删除它们。在较旧的编译器中,您只需将它们声明为私有且未实现。
8赞
jamesdlin
8/6/2010
#3
复制构造函数和复制赋值运算符的问题在于,如果未显式声明实现,编译器会自动生成实现。
这很容易导致意想不到的问题。如果一个类有一个非平凡的析构函数,它几乎总是需要为复制构造函数和复制赋值运算符提供自己的实现(这是三大定律),因为默认的编译器生成的构造函数通常会做错误的事情。
违反三巨头定律通常会导致错误,例如数据成员的双重释放和内存损坏。出现这类错误的情况并不少见,因为该类的作者从不费心去考虑复制行为,而且因为消费者很容易无意中复制对象。
除非类的作者实际上已经考虑过如何正确复制该类的实例(或者除非该类有一个微不足道的析构函数),否则最好明确禁止复制以避免潜在的问题。然后,可以推迟实现可复制性,直到有实际需要为止。
评论
4赞
David
8/6/2010
这正在成为“五大法则”,即将推出的标准C++0,并添加了移动构造函数/赋值!
1赞
jamesdlin
8/7/2010
@David:move 构造函数/move-assignment 运算符将选择加入(如果您省略它们,编译器将不会为您生成它们)。
0赞
David
8/7/2010
你是对的,但如果你关心性能,你也会提供它们。
上一个:如何实现只有一个指针的双链表?
评论