2014-08-31 71 views
1

Common wisdom是,如果你可以通過一個純虛擬析構函數來創建一個類的抽象。應該可以初始化具有未覆蓋的純虛擬析構函數的類嗎?

引述Herb Sutter

所有的基類應該有一個虛析構函數(見的原因你最喜歡的C++的書)。如果類應該是抽象的(你要防止其實例化),但它不會發生在任何其他的純虛函數,一個共同的技術,使析構函數純虛:

然而,下面的代碼編譯爲我GCCVC

#include <iostream> 

struct base { 
    virtual ~base() = 0; 
}; 

base::~base() { std::cout << "base destructor\n"; } 

struct derived : base { }; 

int main() { 
    derived d; 
} 

已經改變的東西在C++ 11,我是不知道的?

順便說一句,這個問題的動機是一個answer I gave five years ago和突然挑戰commenter

+0

爲什麼它不能編譯?您正在實例化派生對象,而不是基礎對象。只有你的基礎是抽象的,因爲你的派生類有默認的析構函數。 – Horstling 2014-08-31 13:29:42

+0

'有一個純虛擬構造函數'=>'有一個純虛擬析構函數嗎? – Gluttton 2014-08-31 13:43:01

+0

@Gluttton哎呀,謝謝。 – Motti 2014-08-31 13:51:06

回答

2

derived類有一個隱式定義的(由編譯器提供的)虛擬析構函數,它不是純粹的,它重寫了基本析構函數。由於這個原因derived不是一個抽象類。它可以被實例化。

這與C++ 11無關。這就是自C++ 98以來一直如此。製作一個基類析構函數純虛擬是一種使這個類只有這個類抽象的方法。編譯器在派生類中提供的析構函數將是非純虛函數,它將自動「取消」那些類中的抽象性(假設沒有其他純虛函數是從基類繼承的)。

+0

Derived的析構函數不會覆蓋基的。想想覆蓋是什麼意思。 – 2014-08-31 13:59:46

+0

@H Walters:呃...是的,派生析構函數確實會覆蓋虛擬基礎析構函數。而這正是覆蓋的意義。 – AnT 2014-08-31 14:02:04

+0

mea culpa ...我指的是dtor的鏈條而不是隱藏的事實,但考慮到標準將dtor's描述爲壓倒一切,它就贏了。 – 2014-08-31 14:18:10