是否可以通过在基 class 中声明副本 constructor/operator 私有来使派生 class 不可复制?

Can a derived class be made uncopyable by declaring copy constructor/operator private in base class?

我认为理论上这个问题的答案是肯定的。

然而,在实践中,我的编译器 (VS2010) 似乎并没有在以下情况下抱怨:我有一个抽象基础 class 提供一些公共接口(但没有数据成员)和各种子和subsubclasses 派生自它。

class Base 
{
public:
    Base() {}
    virtual ~Base() {}

    virtual void interfaceFunction1() = 0;
    virtual void interfaceFunction2() = 0;
private:
    Base(const Base&);            // all derived classes should be uncopyable
    Base& operator=(const Base&);

    // no data members
};

我的编译器发现即使在 sub- 或 subsubclasses 中实现完整的复制构造函数也没有问题。

如何确保从 Base 派生的每个 class 都是不可复制的?

编辑: 如果我理解得很好,这正是 Scott Meyers 在 Effective C++(第 3 版,2005 年)的第 6 项中用他的 class Uncopyable(此处仅扩展为全界面class)。使他的想法奏效的区别是什么? (我知道他是私继承的,不过应该问题不大)

这应该可以防止编译器为未明确声明的派生 classes 生成复制构造函数。但是,没有什么可以阻止派生的 class 显式声明一个复制构造函数,该构造函数除了调用 Base.

的复制构造函数之外还会做其他事情

无法确保派生的 classes 可实例化但不可复制。

与其将副本 constructor/operator 声明为 private,不如将其声明为已删除。将副本 constructor/operator 声明为私有并不是使派生的 classes 不可复制的最佳解决方案。如果您希望基 class 完全不可复制,则将副本 constructor/operator 声明为 deleted 因为复制仍然可以在 [ 的成员函数内进行=17=]Base 因为私有成员可以访问 class 的函数。您可以使用删除的 C++11 功能:

Base(const Base&) = delete; // copy constructor
Base& operator=(const Base&) = delete; // copy-assignment operator

但是将复制 constructor/operator 声明为 private 也是正确的,只要您知道复制仍然可以在 [=17= 的成员函数内进行]基础.

在 C++11 及更高版本中,可以选择声明已删除的构造函数。

struct X {
  X( const X& ) = delete;
};

现在,任何从 X 派生的依赖复制构造函数的东西都不会编译。 当您想避免出现问题时,这是最有用的,因为编译器会自动生成构造函数...