使用已删除的副本构造函数初始化抽象类

时间:2019-02-11 10:46:29

标签: c++ c++11

我有一个抽象类,该类具有已删除的复制构造函数和复制赋值运算符,旨在用作公共接口:

struct connection {
    // Make object non copyable.
    connection(const connection &) = delete;
    auto operator=(const connection &) -> connection & = delete;
    // Make class abstract.
    virtual ~connection() = 0;
  };

我正在尝试创建一个从其继承的类:

struct abstract_connection : connection {...};

但是在构造函数中出现以下错误:

constructor for 'abstract_connection' must explicitly initialize the base class 'connection' which does not have a default constructor

为什么删除复制构造函数和运算符时会发生这种情况?

3 个答案:

答案 0 :(得分:4)

根据标准:

  

[class.default.ctor#1]

     

[...]如果类X没有用户声明的构造函数,则将没有参数的非显式构造函数隐式声明为默认值([dcl.fct.def])。 [..]

由于您已经通过删除用户声明复制构造器,因此需要用户提供默认构造器:

struct connection {

    connection(const connection &) = delete;
    auto operator=(const connection &) -> connection & = delete;
    virtual ~connection() = 0;

protected: // You likely want to make it protected.
    connection() = default;
};

答案 1 :(得分:2)

Scott Meyers在有效现代C ++中,第17页,第109页清楚地解释了自动生成特殊成员函数的规则。

简而言之,每当您重新定义/覆盖构造函数时,都需要定义所有需要的构造函数。由于已删除复制构造函数,因此需要定义基类的默认构造函数。这是因为定义派生类时使用的是默认构造函数。

此代码struct abstract_connection : connection {...};(没有任何给定信息)意味着您最有可能使用abstract_connection中的默认ctor初始化connection。但是未定义connection中的默认ctor。

此外,即使您认为dtor是虚函数,也需要定义它。下面的代码编译并运行here

struct connection
{
    connection() = default;
    connection(const connection &) = delete;

    auto operator=(const connection &) -> connection & = delete;

    virtual ~connection() = 0;
};

connection::~connection()
{}

struct abstract_connection : connection
{
    abstract_connection() : connection()
    {}

    ~abstract_connection() = default;
};

int main()
{
    abstract_connection foo;
}

答案 2 :(得分:0)

您将复制构造函数定义为您自己(=删除)。因此Compiler看到了这一点,并且没有生成默认的构造函数。因此,在这种情况下,当定义从基类连接继承的新类abstract_connection时,编译器不知道如何为新的派生类abstract_connection构造函数。因此它报告了该错误。