2013-08-19 35 views
1

所以我有一个类层次结构,其基本上具有Entity类作为父抽象类和一束从它派生的其他类的的STL矢量调用一个特定对象的功能,如DoorPlayerGround上多态对象

我也有一个三维vector存储指针Entity类型的对象,我用这个派生对象填充这个vector。 在Door类中,我有一个名为isOpen()的方法,它简单地返回bool。此函数特定于Door类,并且在Entity类中以及它的任何其他派生类型中均未找到(因为我不需要检查例如Ground对象是否打开)。现在

,知道有在vectori位置,jkDoor存在类型的对象,我想调用的方法isOpen像这样:vector[i][j][k]->isOpen()。不幸的是,当我这样做时,编译器返回class Entity has no member named isOpen()。这是可以理解的,因为函数isOpen()Door类是排他性的,但是为了使这种调用成为可能,我可以做些什么?

+1

不要只告诉我们你的代码; ***显示***它*更*更有效率。其次,['dynamic_cast <>'](http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used)可能有些用处您。不要只是把它扔进去,阅读如何使用它**先**。 – WhozCraig

回答

2

解决此问题的一种方法是首先将其投射到Door *。但是,为了减少这种类型的安全性,您应该使用dynamic_cast<Door *>()。如果Entity尚不具有虚拟方法,则可以添加虚拟析构函数。

class Entity { 
    //... 
    virtual ~Entity() {} 
}; 

void foo (Entity *e) { 
    //... 
    Door *door = dynamic_cast<Door *>(e); 
    if (door) { 
     if (door->isOpen()) { 
      //... 
     } 
    } 
    //... 
} 
2

简短的回答:

演员实体下降到门:static_cast<Door*>(vector[i][j][k])->isOpen()

龙答:

你的设计是不妥当的,如果你需要知道具体的派生类型是在特定的位置。解决这个问题可能很简单,只需将isOpen()函数移动到实体,并返回true即可。或者它可能需要重新考虑与vector成员一起使用的代码。

+4

如果被指向的实体* *实际上是一个'Door'或者一个派生的'Door'进一步下层,这是**未定义的行为**,并且最肯定会崩溃。 'static_cast <>'不是*这里使用的类型。看到它的描述[在这个问题和答案](http:// stackoverflow。com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used)为什么。 – WhozCraig

+0

你会想使用'reinterpret_cast',而不是'static_cast' - 尽管这种方法不是推荐的方法。长远的答案更符合实际 - 修复设计。 –

+0

啊,谢谢你建议使用类型转换。 在班级重新设计方面,你有什么建议,我会怎么做呢?看起来,与同一个父类的多个对象的向量是我的程序不可或缺的:( – Nonomus

2

考虑多态铸造用dynamic_cast<>对于引用如果目标类型是不兼容的,将简单的返回NULL会抛出异常(std::bad_cast),但指针的语言支持,所以......假设你的基类和它的派生确实是多态的(即至少一个虚拟方法):

Door* pDoor = dynamic_cast<Door*>(vector[i][j][k]); 
if (pDoor) 
    pDoor->isOpen(); 

有关设计的评论版主。意见就像...是的。每个人都有一个。