代码之家  ›  专栏  ›  技术社区  ›  ruipacheco

用已删除的复制构造函数初始化抽象类

  •  1
  • ruipacheco  · 技术社区  · 6 年前

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

    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 回复  |  直到 6 年前
        1
  •  4
  •   Holt 111111    6 年前

    根据标准:

    [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;
    };
    
        2
  •  2
  •   Constantinos Glynos    6 年前

    由Scott Meyers,项目17,P.109在有效的现代C++中清楚地解释了自动生成特殊成员函数背后的规则。

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

    本代码 struct abstract_connection : connection {...}; (没有任何给定的信息)意味着您最有可能初始化 abstract_connection 使用来自的默认ctor 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;
    }
    
        3
  •  0
  •   Loc Tran    6 年前

    您将复制构造函数定义为您自己(=delete)。所以编译器看到了这一点,它不会生成默认的构造函数。因此,在这种情况下,当定义从基类连接继承的新类抽象连接时,编译器不知道如何为新的派生类抽象连接做构造函数。所以报告了这个错误。