2012-11-22 282 views
3

我是C++的新手,我很难弄清楚我的虚拟函数有什么问题。所以,这里是我有:

GEntity.h从基类C++调用虚拟方法

class GEntity 
{ 
public: 
    //... 
    virtual void tick(void); 
    virtual void render(void); 
    //... 
}; 

GEntity.cpp

//... 
void GEntity::tick(void){} 
void GEntity::render(void){} 
//... 

GLiving.h

class GLiving : public GEntity 
{ 
public: 
    //... 
    virtual void tick(void); 
    virtual void render(void); 
    //... 
}; 

GLiving.cpp

//... 
void GEntity::tick(void){} 
void GEntity::render(void){} 
//... 

然后,我有从GLiving(玩家,敌人),它们实现了自己的这两种方法的版本获得其他类: Player.h

class Player : public GLiving 
{ 
public: 
    //... 
    void tick(void); 
    void render(void); 
    //... 
}; 

Player.cpp

//... 
void GEntity::tick(void) 
{ 
    //Here there's some actual code that updates the player 
} 
void GEntity::render(void) 
{ 
    //Here there's some actual code that renders the player 
} 
//... 

现在,如果我声明一个Player类的对象,并调用render/tick方法,一切都很顺利,但是我处于一种情况,我将我的播放器添加到GEntity的ArrayList(一个我创建的结构体),然后,当我将它返回时,我得到它作为一个GEntity,我需要调用渲染/滴答方法,而不知道它的派生类... 我已经尝试使用上面的代码,但我得到一个访问冲突行中,我打电话或者渲染或刻度方法,对提取的GEntity ...
...是我想甚至可以实现的目标?
(抱歉,如果我的英语不太好,但我是意大利)

+3

这个问题可能存在于'arraylist'中。它是否包含指向“GEntity”或“GEntity”实际实例的指针? – Yakk

+0

数组/结构声明怎么样?这是关键。 – Ajay

+0

它包含实际实例 – Sylar

回答

3

如果你有GEntity一个数组,那么,每次“加”派生型,这相当于情况:

GEntity g; 
Player p; 
g = p; // object slicing, you assigned a Player to a GEntity object. 
g.render(); // GEntity::render() gets called 

在另一方面,可以使用一个指针指向一个基类来访问派生方法:

GEntity* g; 
Player p; 
g = &p; 
g->render(); // calls Player::render() 

因此,一个方法来处理多态性的容器被以具有阵列/容器(优选智能)指向基本cl的指针屁股。这个例子使用原始指针为简单起见,但你应该在实际代码中使用smart pointers

std::vector<CEntity*> entities; 
entities.push_back(new Player); 
entities.push_back(new GLiving); 

// some c++11 
for (auto e : entities) { 
    e->render(); 
} 
+0

你不应该写'for(_auto_e:entities) '? – Mikhail

+0

@Mikhail确实,谢谢! – juanchopanza

+0

好,谢谢!有效! ...我仍然习惯Java – Sylar