C++ 11接口纯虚析构函数

vla*_*don 5 c++ pure-virtual language-lawyer virtual-destructor

UPD.有一个标记,它是这个问题的副本.但在那个问题中,OP问如何使用default来定义纯虚拟析构函数.这个问题是关于有什么区别的.

在C++(如果可能的话,最新标准)中,使用空体实现定义纯虚拟析构函数和仅使用空体(或默认值)之间的真正区别是什么?

变式1:

class I1 {
public:
    virtual ~I1() {}
};
Run Code Online (Sandbox Code Playgroud)

变式2.1:

class I21 {
public:
    virtual ~I21() = 0;
};

I21::~I21() {}
Run Code Online (Sandbox Code Playgroud)

变式2.2:

class I22 {
public:
    virtual ~I22() = 0;
};

I22::~I22() = default;
Run Code Online (Sandbox Code Playgroud)

更新我发现Variant 1和Variants 2.1/2.2之间至少有1个区别:

std::is_abstract::value适用false于变体1,true适用于变体2.1和2.2.

Demo

可能有人可以发现2.1和2.2之间的区别?

nsu*_*ron 9

正如您所指出的,I1和I2*之间的区别在于,添加= 0使类成为抽象.事实上,当你没有任何其他函数是纯虚拟时,使析构函数成为虚拟是一个使类抽象的技巧.我说这是一个技巧,因为如果你想要破坏析构函数的任何派生类(在这里你会),析构函数不能保持未定义,那么你仍然需要定义析构函数,无论是空的还是默认的.

现在,空的或默认的析构函数/构造函数(I21和I22)之间的区别更加模糊,没有太多的写入.建议使用default,作为一种新的习惯用语,使你的意图更清晰,显然,给编译器一个优化的机会.引用msdn

由于普通特殊成员函数的性能优势,我们建议您在需要默认行为时更喜欢在空函数体上自动生成特殊成员函数.

除了可能的性能改进之外,两者之间没有明显的差异.= default是从C++ 11开始的方式.