C++11接口(interface)纯虚析构函数

标签 c++ language-lawyer pure-virtual virtual-destructor

更新。有一个标记,它是 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

Demo

可能有人能发现 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/

相关文章:

c++ - 来自使用 ffmpeg 的文件的音频流

c++ - 二叉搜索树中序遍历递归函数不能正常工作

c++ - 用整型变量重载类名

c++ - 纯虚方法只能在直接派生类中实现——为什么?

c++ - c++ Clion 和 VS2019 中的纯虚拟析构函数

c++ - 删除所有构造函数(或其他函数)的最佳样式?

c++ - 用 gcc 编译 asio

c++ - "typename qualified-id"引用非类型参数声明中的类型

c - 别名结构和数组是否合法?

c++ - 友元函数不能访问私有(private)成员变量