boost::noncopyable是如何工作的?

How does boost::noncopyable work

本文关键字:工作 何工作 noncopyable boost      更新时间:2023-10-16

在我的c++实践中,我偶然发现了两个愚蠢的问题:

  1. AFAIK在c++中的复制构造函数和赋值操作符不被继承…那么boost::noncopyable在这种情况下如何帮助禁止这些东西呢?<>之前类X: private boost::noncopyable{};有必要只使用私有继承来实现目标吗?

  2. 是否只有一种方法声明赋值操作符

    MyClass&operator= (const MyClass &);
    和声明
    是一样的吗?void operator= (const MyClass &);
    const MyClass&operator= (const MyClass &), 之前? 

在c++ 11及以后的版本中,通过将其声明为=delete(最好是public)来工作。然而,在c++ 11之前,这是不可能的,并且使用了两种技术的组合:

  • 声明方法private
  • 不要实现
  • 方法

通过将方法设为私有,它不能被非友元类调用。因此,任何试图调用该函数的代码都将导致编译错误。

实际上,类仍然可以复制自己。因此,这个方法不会被实现,你会得到一个链接器错误。

继承boost::noncopyable将阻止第二个用例,然而,它也阻止编译器生成一个有效的默认复制构造函数…因为它们会违反前面的约束。

注意,如果你真的需要,你可以通过调用这些"不可复制"类的普通构造函数来为继承类编写复制构造函数。

对于你的第二个问题:是的,你可以给它任何你想要的返回类型,尽管你不能再写a = b = c;了。

复制构造函数和复制赋值操作符不能被继承,这是正确的。幸运的是,我们不需要继承它们来实现这一目标。如果你继承了一个不能复制的类,那么这个派生类就不能被复制,也不能在它的复制构造函数中调用基类的复制构造函数。

必须从看起来像

的类继承
struct NonCopyable {
    NonCopyable & operator=(const NonCopyable&) = delete;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable() = default;
};

足以阻止编译器在派生类中生成复制和赋值。您可以提供您自己的并覆盖它,但那样就没有意义了。

1)当一个对象被构造时,所有的成员对象和基对象也必须被构造。由于noncopyable::noncopyable(const noncopyable &)是私有的,noncopyable永远不能被复制构造。因此,任何包含它作为成员或基类的对象也永远不能被复制构造。

2)可以用上述三种方式中的任何一种声明赋值操作符。不,它们不是"同一件事"。一个返回可变引用,一个返回const引用,一个返回void。如果您尝试对赋值操作符的结果进行操作,差异将会很明显。考虑这个程序片段:

a = b;
(a = b).foo()

第一行将与任何赋值操作符进行相同的操作。第二行将根据您使用的赋值操作符而变化。