是否可以通过在基 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 派生的依赖复制构造函数的东西都不会编译。
当您想避免出现问题时,这是最有用的,因为编译器会自动生成构造函数...
我认为理论上这个问题的答案是肯定的。
然而,在实践中,我的编译器 (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 派生的依赖复制构造函数的东西都不会编译。 当您想避免出现问题时,这是最有用的,因为编译器会自动生成构造函数...