我有一个抽象类,该类具有已删除的复制构造函数和复制赋值运算符,旨在用作公共接口:
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
为什么删除复制构造函数和运算符时会发生这种情况?
答案 0 :(得分:4)
根据标准:
[...]如果类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构造函数。因此它报告了该错误。