宏禁止类复制和分配.谷歌-vs- Qt

Rob*_*rtL 35 c++

要禁止复制或分配类,通常的做法是将复制构造函数和赋值运算符设为私有.谷歌和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)

  • 继承方法是否会使代码生成膨胀? (5认同)
  • 将它们声明为私有将产生编译器错误 (3认同)
  • 在继承自另一个类的类上使用boost :: noncopyable需要多继承及其相关的陷阱 - 包括@ThreeBit提到的对象代码膨胀的可能性.谷歌风格手册不鼓励多重继承,这解释了为什么它提倡宏而不是非复制.(另一方面,谷歌也不鼓励使用宏,尽管这个宏是一个例外.) (2认同)

sel*_*tze 9

请参阅Boost.Utility,特别是boost :: noncopyable.它不是宏,而是具有私有副本和赋值的基类.它可以防止编译器在派生类中生成隐式副本和赋值.

编辑:对不起,这不是原始问题的答案.顺便说一句,boost :: noncopyable使用const引用作为赋值运算符的返回类型.我的印象是返回值的类型无关紧要,因为它不应该被使用.仍然,使运算符私有不会阻止在类或朋友中使用,在这种情况下,非常规的返回类型(如void,const引用等)可能会导致编译错误并捕获其他错误.


sha*_*oth 5

没有实际的区别.赋值运算符签名在风格上有所不同.通常有一个赋值运算符返回一个允许链接的引用:

a = b = c;

但是返回的版本void也是合法的,并且对于仅用于声明操作符private并因此禁止使用的唯一目的的情况将适用.