2012-05-31 42 views
2

這是問題所在—我有兩個類是這樣的:指向繼承的類實例作爲函數參數

class A 
{ 
    //some fields and methods 
    void niceMethod(); 
}; 

class B : public A 
{ 
    void niceMethod(); 
}; 

class C : public A 
{ 
    void niceMethod(); 
}; 

和功能

void myFunc(A** arrayOfABC); 

//雙*是注意到我要去修改論點。

我想做的事:

(*arrayOfABC)[i].niceMethod(); 

在我的功能,讓做不同的事情,當我經過燒烤或Cs的陣列的功能。

但後來我嘗試調用它像

B* bees = NULL; 
    myFunc(&bees); 

我有「B的參數類型**是A型**的參數不兼容」。

我知道我可以將B或C作爲A傳遞給函數f(A),但指針有什麼問題?

+1

這樣的事情可以接受嗎? 'B * bees = NULL; A * ptrs [] = {bees}; myFunc(ptrs);' –

+0

不錯的解決方案,但我決定重新考慮我的projectc結構以避免這個問題。 –

回答

3

編譯器是正確的,它的確是不兼容的。試想一下:

B* bees = new B[2]; 
myFunc(&bees); // Imagine that it's allowed 

現在裏面myFunc你這樣做:

void myFunc(A** arrayOfABC) { 
    // This is OK: 
    arrayOfABC[0] = new C(); 
} 

這應該是允許的,因爲C延伸A。但是,從myFunc返回時,您的bees將包含C,這並不好。

若要解決此問題,請創建一個數組A*,並使用指向B的指針填充它。

P.S.不要忘記虛擬niceMethod,否則它不會按照您的預期工作。

2

您可以將B*轉換爲A*,但不能將B**轉換爲A**

假設A是水果和B是蘋果,然後A*是一個小箭頭可以指向一個水果(任何水果)和B*是一個小箭頭可以指向一個蘋果(並且僅一個蘋果)。你可以拿一個蘋果箭,將它重新標記爲一個水果箭,並把它交給一個預計水果箭的人。它確實指向了水果,因爲蘋果是一種水果。到目前爲止這麼好,這裏沒有什麼驚喜。

現在A**是一個小箭頭可以指向一個小箭頭,可以指向一個水果(任何水果),以及B**是一個小箭頭可以指向一個小箭頭可以指向一個蘋果(只有蘋果)。如果你拿走後者會發生什麼,並把它交給一個預計前者的人?這個人可以沿着箭頭指向一個可以指向一個水果(任何水果!)的箭頭,拿起那個第二個箭頭,並將其轉向並指向一根香蕉。

現在不幸的蘋果傢伙傢伙誰曾經有一個雙蘋果箭頭沿着第一箭去,然後沿着第二箭頭去那應該指向一個蘋果,發現香蕉還有,水果,他認爲這是他悲慘生活中的第一次。如果你問我,這是一個非常不幸的情況。從這一點開始,我們不應該感到驚訝!

+0

有趣的答案,男人! –