2012-05-24 96 views
-2

我從基類到派生類型轉換時遇到了問題(因爲我確定該對象是確切類型)。 這裏是我的代碼(簡化):C++中的類型轉換問題

class MyCollection 
{ 
public: 
Element* Get(int i) { 
    return elements[i]; 
} 
void Add(Element* element) { 
    //finding i 
    elements[i] = element; 
} 
private: 
Element* elements[100]; 
} 

class Element { 
public: 
    int ID; 
} 

class SpecialElement : public Element 
{ 
public: 
SpecialElement(char* name) { 
    this-> Name = name; 
} 
char* GetName() { return Name; } 
private: 
char* Name; 
} 

現在,當我加入SpecialElement的MyCollection的對象,當我把斷點添加的時刻,投我的Add方法的參數在立即窗口和調用GetName方法是返回我物品的名稱,但是當我做這樣的事情時:

void main() { 
MyCollection coll = new MyCollection(); 
coll.Add(new SpecialElement("MyName")); 
SpecialElement* foundElement = (SpecialElement*)coll->Get(0); 
foundElement->GetName(); //Error 
} 

我想知道爲什麼?不是創建SpecialElement類型的對象嗎?

+5

請勿使用'void main()':http://www2.research.att.com/~bs/bs_faq2.html#void-main – chris

+1

過度使用動態分配。不好的使用字符串。並濫用積分。 – Puppy

+3

集合的味道像**切片**全... –

回答

6
Element* Get(int i) { 
    return elements[i]; 
} 
void Add(Element* element) { 
    //finding i 
    elements[i] = element; 
} 

這怎麼編譯?您將Element*分配給Element,反之亦然,但它們完全不同。你的整個邏輯是荒謬的。

你過度使用動態分配,假設參考語義和錯誤的char*字符串。獲取一本C++書籍。

另外,這個類已經存在 - 它是std::array<Element*, 100>。或者std::vector<Element*>,如果你想要動態大小。

6

您正在將它投射到基地Element,從而切分您的SpecialElement對象。從基地Element轉換回原始類型已丟失數據Name,因爲這不是基數的一部分。

AFAIK,你不能做你想做的事情。

+0

他可以做到這一點,但是這個存儲陣列需要包含*指針*(例如'Element * elements [100]'而不是'Element elements [100]')以避免切片。 – Mud

1

您應該使用Element* elements[100];並適當地更新您的代碼,否則使用對象分配而不是指針分配殺死多態性。