2014-04-02 98 views
1

我是新的C++編程所以這個問題可能是基本的,但在這裏它是:C++指針轉換

我有四節課 - A,B,C和D.它們之間的關係定義如下:

class B : public A; 
class D : public C; 

A是一個抽象類(所有方法都是純虛擬的)。 D類實現了C不支持的Print()函數。

//Class D - some code 
void Print() 
{ 
    //some code 
} 

類A具有STL ::列表

//Class A - some code 
protected: 
    list<C*> myObjects; 

在類BI具有推向myObjects指針類型d的對象的函數(同樣保持指針類C的對象, D繼承C)完美的作品。

Class B : public A 
{ 
    // Some code 
    D* obj = new D(...); 
    myObjects.push_back(obj); 
    return obj; 
} 

最後,在課堂上BI有超過myObjects迭代(從A類繼承)的功能,像這樣:

for(list<C*>::iterator it = myObjects.begin(); it != myObjects.end(); it++) 
{ 
    //I wish to call the function D.Print() but I get an error! 
    D *a = *it; 
    a->Print(); 
} 

錯誤狀態:

error C2440: 'initializing': cannot convert from 'std::_List_iterator<_Mylist>' to 'D*' 

我下如果「a」是指向D類對象的指針,那麼如果我給它指向迭代器引用的指針的值(指向指向D類型對象的指針),我可以調用Print ()。

你能幫忙嗎? 在此先感謝!

+0

@juanchopanza我試過,但由於打印沒有在C類中定義,我得到C2039:'打印':不是C.的成員。 – Tal

+0

對不起,我錯過了那部分。那麼你需要嘗試'dynamic_cast'。最好是用代碼而不是散文表達相關信息。 – juanchopanza

+0

而不是僅僅試圖解釋你有什麼,用小的代碼外的代碼片斷,爲什麼不創建一個[最小,完整和可驗證的例子](http://stackoverflow.com/help/mcve),你可以給我們看一看?這會讓你更容易理解你有什麼和可能發生的事情。 –

回答

1

嘗試

D *a=dynamic_cast<D *>(*it) 

列表的內容可能是d的對象,但這只是在運行時知道的,所以編譯器不能在編譯時知道,如果列表包含的d對象或C.其他派生類

根據記錄,該代碼編譯的ideone

+0

我得到錯誤C2683:'dynamic_cast':C不是一個多態類型 – Tal

+0

@Tal你說C有虛擬方法...嘗試了一個與g ++的虛擬示例,它的工作。 – jsantander

+0

我錯了。 A是抽象的。 C不是。對於混淆抱歉 - 我編輯了原始問題。 – Tal

2

沒有必要試圖轉換爲D類型,如果你定義

virtual void Print() = 0; 

in class C

然後,你可以通過編寫

C *a = *it; 
C->Print(); 

,或者甚至更好利用多態性,

(*it)->Print(); 

如果你不能做到這一點,那麼你可以使用一個dynamic_cast,或簡單地存儲list<D*> myObjects;代替。

+0

顯然:「D類實現了一個Print()函數,C沒有。」 – jsantander

+0

@jsantander:哎呀。忘了閱讀規範。不會是最後一次;-) – Bathsheba

+0

但是,您的解決方案是完全有效的...如果允許更改C的API ... – jsantander

0

請確保Print被聲明爲純虛在C,然後只需使用C指針,而不是D在打印循環。您不需要任何投射,這就是虛擬功能的用途。