在c++中,如果首先禁止默认构造,那么禁止复制构造有意义吗

In c++, Does it make sense to prohibit copy construction if the default construction is prohibited in the first place?

本文关键字:禁止 复制 有意义 c++ 默认 如果      更新时间:2023-10-16

我正在进行一个代码实现,目的是不让任何人生成特定类的对象。以下是代码片段:

class CantInstantiate
{
CantInstantiate();
CantInstantiate(const CantInstantiate&);
...
};

如果默认构造函数已经被设置为private undefined(前提是没有其他构造函数(,那么是否真的需要将复制构造函数设置为private-deefined?当我们一开始没有原始对象时,防止复制对象有什么好处?请解释。提前谢谢。

如果目的是阻止创建类的实例,那么您需要确保不能调用任何构造函数。如果您没有明确禁止复制构造,那么您就让编译器根据导致删除隐式声明的复制构造函数的条件来决定是否包含复制构造,这些条件是:

- 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));

现在无可否认,上面的代码可能会产生意想不到的行为,如果你试图这样做,但它确实编译了,任何像样的编译器都会发出警告。这种方法的实用性将完全取决于内宣布的其他内容

我认为,如果这个想法是停止创作,那么你需要确保所有的施工方法都被阻止。因此,显式删除默认构造函数、复制构造函数和移动构造函数是一种更好的方法。这发出了一个更明确的意向声明,我认为它应该阻止所有的施工方法。

class CantInstantiate
{
public:
CantInstantiate() = delete;
CantInstantiate(const CantInstantiate&) = delete;
CantInstantiate(CantInstantiate&&) = delete;
...
};