更新。有一个标记,它是 this question 的重复项。 .但是在那个问题中,OP 询问如何使用 default
来定义纯虚拟析构函数。这个问题是关于有什么区别。
在 C++(如果可能的话,最新标准)中定义具有空主体实现的纯虚拟析构函数与仅空主体(或默认)之间的真正区别是什么?
变体 1:
class I1 {
public:
virtual ~I1() {}
};
变体 2.1:
class I21 {
public:
virtual ~I21() = 0;
};
I21::~I21() {}
变体 2.2:
class I22 {
public:
virtual ~I22() = 0;
};
I22::~I22() = default;
更新 我发现变体 1 和变体 2.1/2.2 之间至少有 1 个不同:
std::is_abstract::value
对于变体 1 为 false
,对于变体 2.1 和 2.2 为 true
。
可能有人能发现 2.1 和 2.2 之间的区别?
最佳答案
正如您所指出的,I1 和 I2* 之间的区别在于添加 = 0
会使类抽象。事实上,使析构函数成为纯虚拟是一个技巧,可以在您没有任何其他函数可以成为纯虚拟时将类抽象化。我说这是一个技巧,因为如果您想析构它的任何派生类(在这里您会),析构函数不能未定义,那么您仍然需要定义析构函数,无论是空的还是默认的。
现在,空的或默认的析构函数/构造函数(I21 和 I22)之间的区别更加模糊,那里没有写太多。推荐的是使用default
,既作为一种新的惯用语让你的意图更清晰,显然,给编译器一个优化的机会。引用 msdn
Because of the performance benefits of trivial special member functions, we recommend that you prefer automatically generated special member functions over empty function bodies when you want the default behavior.
除了这种可能的性能改进之外,两者之间没有明显的区别。 = default
是从 C++11 开始的方式。
关于C++11接口(interface)纯虚析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37777606/