2016-10-04 126 views
1

我有此類結構,其中D類和CLASSE祖父母是相同C++使用繼承父類

classB : classA; 
classC : classA; 

classD : classB; 
classE : classC; 

然後我需要傳遞對象classF

classF : classA; 
function(classF *func); 
的函數轉換成一對象類

是否可以將類型爲classD和classE的對象傳遞給需要類型爲classF的函數? 樣本實施如下: 是否有可能只投給他們的共同祖父母?

classD *d = new classD(); 
classE *e = new classE(); 

classA *func = (classA*)d; 
function(func); 

func = (classA*)e; 
function(func); 
+1

請顯示真實密碼。在這種情況下,你應該使用'static_cast'。 –

+3

如果'classF'是必需的,你需要'classF'。如果'classA'提供'function(...)'中需要的所有內容,則相應地更改參數類型。 – grek40

+0

這取決於什麼功能。它可以調用classF的特定方法。 – Daniele

回答

3

不,不,另一次沒有。

,根本不符合要求的線是這樣的:

function(func); 

這需要向下轉換,即 - 一個從父類到它的子類鑄造。 downcast不會隱式發生,這意味着該行不會編譯(但是您提供了編譯代碼,您已經知道這一點)。以下將編譯:

function((classF*)func); 

但你不應該使用它。 downcast的結果是未定義的,除非該引用最初屬於該類型。所以,這是好的:

classF *f = new classF(); 
func = (classA*) f; 
function((classF*)func); 

但是,這並不:

classB *b = new classB(); 
func = (classA*) b; 
function((classF*)func); 

編輯如果使用專用的C++類型轉換操作dynamic_cast進行喪氣添加

,那麼代碼在運行時,確保羽化是正確的。所以:

classF *f = new classF(); 
func = (classA*) f; 
classF *newf = dynamic_cast<classF *>(func); // Okay 
classB *b = new classB(); 
func = (classA*) b; 
newf = dynamic_cast<classF *>(func); // newf is now NULL 

這允許運行時檢查你沒有犯過錯。

就我個人而言,我喜歡從不依賴於實際設計,僅用於驗證。在這種情況下,動態轉換引用而不是指針會更好。動態轉換不正確的指針會導致NULL。動態投不正確的引用拋出一個異常:

classF *f = new classF(); 
func = (classA*) f; 
classF *newf = &dynamic_cast<classF &>(*func); // Okay 
classB *b = new classB(); 
func = (classA*) b; 
newf = &dynamic_cast<classF &>(*func); // Throws an exception 
2

如果你想發揮一個classF指針,你應該傳遞一個classF指針。您的代碼甚至不應該這樣進行編譯,因爲功能的需要classF,你給它一個classA

你能得到這個與類轉換爲classF,你不應該這樣做編譯。這會讓你進入未定義的行爲狀態,因爲你基本上會對你的編譯器說謊,並說「這個其他類是classF指針」,這不會是真的。

你總是可以放心地做它轉換爲基類的指針(像你在你的榜樣與鑄造classA做)

你也應該切換從C風格的強制轉換成C++風格的轉換(如static_castdynamic_cast)。這也可以幫助你在你的情況。通過動態演員,你可以安全地將一個班級轉化爲一個訓練有素的班級。

像這樣:

class A {}; 

class B : public A {}; 
class C : public A {}; 

A* b-obj = new B; 
A* c-obj = new C; 

現在都c-objb-obj是指向A,所以我們不知道了,如果他們是B或C.你可以用dynamic_cast

C* ptr = dynamic_cast<C*>(b-obj); //returns null because b-obj cannot be converted to C* 

C* ptr = dynamic_cast<C*>(c-obj); //does not return null 

檢查此您的代碼可以如下所示:

func = static_cast<A*>(e); // cast to base class. 
//later then. 
classF* funcF = dynamic_cast<F*>(func); 
if(funcF != NULL) 
{ 
    function(func); 
} 

c風格的演員陣容可能會有一些你可能不喜歡的副作用。所以強烈建議熟悉C++強制轉換。