c++ - 在 C++ 中,如果首先禁止默认构造,那么禁止复制构造是否有意义?

标签 c++ constructor copy-constructor default-constructor

我正在经历一个代码实现,其目的是不让任何人创建特定类的对象。这是代码片段:

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

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

最佳答案

如果目的是防止创建类的实例,那么您需要确保不能调用任何构造函数。如果您没有明确禁止复制构造,那么您将根据导致 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 中声明的其他内容......

我认为,如果要停止创建,那么您需要确保阻止所有构造方法。因此,显式删除默认构造函数、复制构造函数和移动构造函数是一种更好的方法。这发出了更清晰的意图声明,我相信它应该阻止所有构造方法。

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

关于c++ - 在 C++ 中,如果首先禁止默认构造,那么禁止复制构造是否有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58647861/

相关文章:

c++ - 使用telnet C++编译 “cin >> a >> b”时出错

java - 初学者Q : optional arguments in Java

Java : can't call overloaded constructor

javascript - 为什么函数在构造函数中声明时不使用 new 关键字?

c++ - C++ 拷贝构造函数中的 const

C++默认复制和赋值运算符

python - 像素着色器中的 Mandelbrot

C++ 下标运算符

c++ - 最简单的 “error: taking the address of a temporary object”修复程序?

c++ - 按值返回时复制构造函数的奇怪行为