我正在通过代码实现,目的是不让任何人创建特定类的对象。这是代码段:
class CantInstantiate
{
CantInstantiate();
CantInstantiate(const CantInstantiate&);
...
};
如果默认构造函数已经设为私有不确定(如果没有其他构造函数,是否真的需要将复制构造函数设为私有不确定?首先没有原始对象时,防止复制对象有什么好处?请解释。预先感谢。
如果目的是防止创建类的实例,那么您需要确保不能调用任何构造函数。如果您没有明确禁止复制构造,那么您将根据导致deleted implicitly-declared copy constructor的条件,由编译器决定是否包含一个副本,即:
- T has non-static data members that cannot be copied (have deleted, inaccessible, or ambiguous copy constructors); - T has direct or virtual base class that cannot be copied (has deleted, inaccessible, or ambiguous copy constructors); - T has direct or virtual base class with a deleted or inaccessible destructor; - T is a union-like class and has a variant member with non-trivial copy constructor; - T has a data member of rvalue reference type; - T has a user-defined move constructor or move assignment operator (this condition only causes the implicitly-declared, not the defaulted, copy constructor to be deleted).
因此,如果您假设有一个类A试图通过仅禁止默认构造并且不包含上面列表中的任何内容来阻止自身的构造,则可以利用隐式副本构造函数获取A的实例,甚至从中继承。例如:
class A
{
A(){};
};
struct B : public A {
B() : A(*a)
{}
A* a;
};
B b;
A a (*static_cast<A*>(nullptr));
现在,上面的代码可能会产生意外的行为,如果您尝试执行任何正确的编译器,但都会编译出警告。这种方法的实用性将完全取决于在A ...中声明的其他内容。
我会争辩说,如果这个想法是要停止创造,那么您需要确保防止所有构造方法。因此,这是一种显式删除以下方法的更好的方法:默认构造函数,复制构造函数和move构造函数。这发出了一个更加清晰的意图声明,我认为它应该阻止所有构造方法。
class CantInstantiate
{
public:
CantInstantiate() = delete;
CantInstantiate(const CantInstantiate&) = delete;
CantInstantiate(CantInstantiate&&) = delete;
...
};