衆所周知,我們可以使用純虛析構函數,就像這樣:如果從析構函數調用純虛函數是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