虚函数:迭代用子类对象填充的向量<base class =“”/>

时间:2011-03-05 00:13:49

标签: c++ oop virtual-functions

简短描述:
我正在迭代向量调用向量中的每个对象上的虚函数,以便执行一系列动作。向量是基类,迭代器也是。所有的对象都是孩子。当调用虚函数时,它执行基类的函数。

(真的)长说明: 我试图模拟一个有一系列行为的生物。我的基类是抽象的,只有两个函数(虚拟),所有子类都被覆盖了:

class Behavior
{
public:
     Behavior();
    ~Behavior(void){}
 virtual void execute(){} 
 virtual BEHAVIOR_TYPE getType() {return m_Type;}


protected:
BEHAVIOR_TYPE m_Type;
};

我创造了许多儿童行为,例如移动,消耗,侦察等。

class Move :
    public Behavior
{
public:
BEHAVIOR_TYPE getType() {return m_Type;}
    enum Direction {N, NE, E, SE, S, SW, W, NW};
Move(DOCO * d);
~Move(void);
void execute() ;
    Direction chooseDirection();
    void setDirection(Direction newDirection);
private:
    Direction m_Direction;
    DOCO *I;
BEHAVIOR_TYPE m_Type;

};

我创建了一个向量,我在其上推送了每个Behavior子类的实例以及遍历它的迭代器:

vector<Behavior> m_Behavior;
vector<Behavior>::iterator bIt;

当生物获得动作序列时,我尝试迭代向量,取消引用迭代器,并调用执行函数:

void World::justDoIt()
{
    for(dIt=myDOCO.begin(); dIt!=myDOCO.end(); ++dIt)
{
    vector<Behavior>::iterator myBehavior=(dIt)->getFirstBehavior();
    vector<Behavior>::iterator end=(dIt)->getLastBehavior();
    for(myBehavior; myBehavior!=end; ++myBehavior)

        (*myBehavior).execute();
}
}

问题在于它执行父函数而不是子函数。

在我对后期绑定的理解中,它应该根据调用它的对象类型而不是调用它的指针类型自动调用适当的函数,并且在我的代码中我预计它会指向儿童对象。

显然我犯了一个错误并以某种方式告诉程序我希望这些被视为父母而不是孩子,但我找不到我的错误。

第二个症状是它不会让我让父项功能纯虚拟,因为它说它不能实例化一个抽象类。我没有在我的代码中的任何地方显式地实例化它,但必须有某个地方我隐式地这样做。然而,我找不到哪里。当然创建一个向量来保存父类的对象不需要实例化父对象,这是我唯一直接引用父类的时候。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:10)

vector<Behavior>使用复制构造函数Behavior::Behavior(const Behavior&);复制您在其中存储的任何内容。这破坏了多态性。您需要在容器中使用指针或智能指针:

vector<Behavior*> m_Behavior; // I will take care of new and delete
vector<shared_ptr<Behavior> > m_Behavior; // easier

如果std::shared_ptr或类似内容中没有std::tr1::shared_ptr#include <memory>,也许您可​​以使用Boost's。

答案 1 :(得分:4)

您正在向矢量添加类的实例。这会产生slicing

您需要做的是将指针添加到行为实例中,并修改循环以执行

(*myBehavior)->execute();