众所周知,我们可以使用纯虚析构函数,就像这样:如果从析构函数调用纯虚函数是UB,为什么我们可以使用纯虚拟desrtuctors?
struct A {
virtual ~A() = 0;
};
A::~A() {}
struct B : A {};
因为标准说,在10.4 [class.abstract] p2
纯虚函数如果调用需要被定义只用...( 12.4 [class.dtor])
后来在12.4 [class.dtor] p9
析构函数可以声明为虚拟的(10.3)或纯虚拟的(10.4);如果程序中创建了该类的任何对象或任何派生类,则应定义析构函数。
什么意味着上面的代码是完全有效 - A::~A
可以是纯虚拟的,它被定义,B::~B
隐式调用A::~A
。
到目前为止,这么好。
然后我读10.4 [class.abstract] p6
:
成员函数可以从一个构造(或析构函数)一个抽象类的调用;对于从这样的构造函数(或析构函数)创建(或销毁)的对象,直接或间接地对纯虚函数进行虚拟调用(10.3)的效果是未定义的。
但是,这正是我们在这里所做的 - 我们从析构函数调用纯虚函数A::~A
。
那么,是不是有某种矛盾?
析构函数是一种特殊情况,因为即使它是纯虚拟的,它仍然必须有一个正文(按照标准)。未定义的部分适用于纯虚拟成员函数(可能没有定义)。 – StoryTeller