如果我有一個名爲「動物」類和派生類「伯德:公共動物」,我可以創造一個鳥這兩種方式:以不同的方式聲明繼承類的實例是否有區別?
Animal *sparrow = new Bird;
Bird *sparrow = new Bird;
兩個預期編譯罰款和工作。它們是否相同?我應該更喜歡一個嗎?
如果我有一個名爲「動物」類和派生類「伯德:公共動物」,我可以創造一個鳥這兩種方式:以不同的方式聲明繼承類的實例是否有區別?
Animal *sparrow = new Bird;
Bird *sparrow = new Bird;
兩個預期編譯罰款和工作。它們是否相同?我應該更喜歡一個嗎?
這條線本身並沒有表現出差異。但是,假設Bird
聲明Animal
上不存在的方法Fly
。你不會是能夠做到:
Animal* a = new Bird;
a->Fly();
,另一方面,這是合法的:
Bird* b = new Bird;
b->Fly();
這裏的區別是事實,C++是一種靜態類型語言的結果。變量的靜態類型是編譯器在驗證諸如方法調用之類的東西時所關心的。由於變量a
的靜態類型爲Animal
,它沒有Fly
方法,因此編譯器將不允許您對其調用Fly
(並非所有動物都可以飛行,因此您必須明確投射到Bird
: dynamic_cast<Bird*>(a)->Fly()
是合法的)。
表達式new Bird
將具有類型Bird*
。如果將派生類型的值分配給基礎類型的變量,編譯器將不會投訴(所有Bird
都是Animal
,所以它應該始終有效)。基本上,編譯器上傳Bird*
到Animal*
。相反是不正確的。並非所有的Animal
s都是Bird
s,所以你必須承擔責任並明確地進行轉換,並告訴編譯器我知道該對象實際上是Bird*
。只有在這種情況下,編譯器纔會讓您使用Bird
的特定功能。因此,一般來說,如果您需要使用Bird
特定成員,則最好使用Bird* b = new Bird;
。
我想我明白了。後續在我的腦海中清除它: 動物* A =新的動物; 動物* B =新鳥; 有了這些聲明,A和B之間是否有區別? (在上面進行了一些修改之前詢問的問題) – Jarred 2010-03-02 19:42:50
@Jarred:是的,由'A'指出的對象並不是一個真正的「鳥」,而由「B」指向的對象實際上仍然是一個「鳥」,而你只是決定不關心(因爲你的功能同樣適用於所有的動物,並且不依賴任何特定的鳥類)。由於'B'是一個'Bird',你可以再次成功地將它下傳到'Bird *'並使用'Bird'特定的成員。將'A'投射到'Bird *'不會成功。 – 2010-03-02 19:48:21
非常感謝您的幫助。 – Jarred 2010-03-02 19:54:42