2011-03-20 135 views
5

當我繼續繼承和上/下鑄造時,我偶然發現了這個問題。爲什麼不允許(代碼被註釋爲顯示不允許的部分)?現在我可以猜測爲什麼它不被允許,但事實上的答案會很好。受保護/私有繼承鑄造

至於那允許的代碼,我知道那是因爲(基地*)是C樣式轉換本質上是一個的reinterpret_cast在C++這反過來又意味着,在這種情況下,它會導致未定義的行爲。如果我錯了,請糾正我。

class Base 
{ 
}; 

class Derived : public Base 
{ 
}; 

class DerivedProt : protected Base 
{ 
}; 

class DerivedPriv : private Base 
{ 
}; 

int main() 
{ 
    Base* a = new Derived(); 
    Base* b = new DerivedProt(); // Not allowed 
    Base* c = new DerivedPriv(); // Not allowed 

    Base* d = (Base*) new DerivedProt(); // Allowed but undefined behavior...? 
    Base* e = (Base*) new DerivedPriv(); // Allowed but undefined behavior...? 
} 

回答

0

聽起來像你是對的。

需要記住的一件事是傳統的面向對象的原則,如LSP只描述公共繼承。非公有繼承屬於繼承和組合之間,基礎子對象是非公開的組合,但您也可以利用依賴於繼承的功能(例如虛擬功能)。

但是,就像組合的子對象一樣,只有類(或其後代,在受保護繼承的情況下)才能獲得子對象的地址。

6

該標準明確指定C風格轉換可以執行此轉換。這是C風格投下的唯一角色,可以做,但沒有C++演員能做。據我所知,結果並不確定;這僅僅是其他演員所不允許的。

+1

即使它不是未定義的行爲,它仍然是一個令人難以置信的壞主意,應該避免。這種轉換非常危險的一件事是,即使沒有繼承關係並且甚至不會產生警告,編譯器也會嘗試去做。 – 2011-03-20 23:11:09

+5

我不得不在線查看Comeau,看看我的編譯器是否得到了這個錯誤。不,reinterpret_cast <>也可以這樣做。 – 2011-03-21 00:31:54

+0

@HansPassant但是'reinterpret_cast'不知道或關心基類。它不能用於向上或向下演員。 – curiousguy 2011-12-19 16:05:52