2012-05-24 65 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];并适当地更新您的代码,否则使用对象分配而不是指针分配杀死多态性。