要禁止复制或分配类,通常的做法是将复制构造函数和赋值运算符设为私有.谷歌和Qt都有宏,使这个变得简单明了.这些宏是:
谷歌:
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
Run Code Online (Sandbox Code Playgroud)
Qt的:
#define Q_DISABLE_COPY(Class) \
Class(const Class &); \
Class &operator=(const Class &);
Run Code Online (Sandbox Code Playgroud)
问题:为什么两个赋值运算符的签名不同?好像Qt版本是正确的.两者之间有什么实际区别?
jal*_*alf 45
没关系.返回类型不是函数签名的一部分,因为它不参与重载解析.因此,当您尝试执行赋值时,无论您是否使用返回类型,两个声明都将匹配.
而且由于这些宏中的所有点都是函数永远不会被调用,所以返回它并不重要void
.
bar*_*son 15
我只想提一下,有一种替代策略可以实现抽象来禁止复制和分配类.我们的想法是使用继承而不是预处理器.我个人更喜欢这种方法,因为我遵循经验法则,尽可能避免使用预处理器.
boost::noncopyable
是一个示例实现.它使用如下:
class A : noncopyable
{
...
};
Run Code Online (Sandbox Code Playgroud)
请参阅Boost.Utility,特别是boost :: noncopyable.它不是宏,而是具有私有副本和赋值的基类.它可以防止编译器在派生类中生成隐式副本和赋值.
编辑:对不起,这不是原始问题的答案.顺便说一句,boost :: noncopyable使用const引用作为赋值运算符的返回类型.我的印象是返回值的类型无关紧要,因为它不应该被使用.仍然,使运算符私有不会阻止在类或朋友中使用,在这种情况下,非常规的返回类型(如void,const引用等)可能会导致编译错误并捕获其他错误.
没有实际的区别.赋值运算符签名在风格上有所不同.通常有一个赋值运算符返回一个允许链接的引用:
a = b = c;
但是返回的版本void
也是合法的,并且对于仅用于声明操作符private
并因此禁止使用的唯一目的的情况将适用.