【发布时间】:2018-10-02 08:40:44
【问题描述】:
在定义接口类时,声明实例化方法的正确方法是什么?
出于显而易见的原因,抽象基类必须具有虚拟析构函数。但是,随后会给出以下编译警告:“'InterfaceClass' 定义了非默认析构函数,但未定义复制构造函数、复制赋值运算符、移动构造函数或移动 赋值运算符”,即“五法则”。
我理解为什么一般应该遵守“五法则”,但它仍然适用于抽象基类或接口吗?
我的暗示是:
class InterfaceClass
{
// == INSTANTIATION ==
protected:
// -- Constructors --
InterfaceClass() = default;
InterfaceClass(const InterfaceClass&) = default;
InterfaceClass(InterfaceClass&&) = default;
public:
// -- Destructors --
virtual ~InterfaceClass() = 0;
// == OPERATORS ==
protected:
// -- Assignment --
InterfaceClass& operator=(const InterfaceClass&) = default;
InterfaceClass& operator=(InterfaceClass&&) = default;
// == METHODS ==
public:
// Some pure interface methods here...
};
// == INSTANTIATION ==
// -- Destructors --
InterfaceClass::~InterfaceClass()
{
}
这是正确的吗?这些方法应该是= delete 吗?是否有某种方法可以声明析构函数是虚拟纯的,同时又以某种方式保持默认?
即使我将析构函数声明为:virtual ~InterfaceClass() = default;,如果我没有显式默认其他四个,我也会收到相同的编译器警告。
Tl;dr:什么是满足接口类“五规则”的正确方法,因为用户必须定义一个虚拟析构函数。
感谢您的时间和帮助!
【问题讨论】:
-
“然后给出以下编译警告” - 由哪个编译器/版本?
-
clang 6.0 警告一个折旧的复制构造函数。 clang-tidy 6.0 静态分析器给出了上面的特定警告字符串。 g++ 4.2.1 似乎没有针对这种情况触发警告。我正在使用 mac os High Sierra 10.13.4
-
基类析构函数应该被保护(防止多态删除)或公共和虚拟(使多态删除安全)。您拥有的受保护和虚拟组合很奇怪。
-
感谢您的提示。我将更新示例以反映这一点。
-
非拥有接口,不拥有,不应该拥有,这是零规则。 en.cppreference.com/w/cpp/language/rule_of_three
标签: c++ abstract-class c++17 virtual-destructor rule-of-three