【问题标题】:Virtual Functions: Iterating over a vector<Base Class> that is populated with subclass objects虚函数:迭代向量<Base Class> 填充有子类对象
【发布时间】:2011-07-09 05:03:09
【问题描述】:

简短说明:
我正在迭代一个向量,该向量在向量中的每个对象上调用一个虚函数,以执行一系列动作。向量和迭代器一样属于基类。所有的对象都是孩子。当调用虚函数时,它会执行基类的函数。

(真的)长描述: 我正在尝试为具有一组行为的生物建模。我的基类是抽象的,只有两个函数(虚拟),所有子类都已覆盖:

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();
}
}

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

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

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

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

任何帮助将不胜感激。

【问题讨论】:

  • 应该有几十个骗子将基类 objects(而不是 pointers)放入 STL 容器,虽然我不能,提款机,找一个。其中一个可能应该成为FAQ entry。

标签: c++ oop virtual-functions


【解决方案1】:

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

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

如果您在#include &lt;memory&gt; 或类似名称中没有std::shared_ptr 或std::tr1::shared_ptr,也许您可​​以使用Boost。

【讨论】:

  • 如果你有std::shared_ptr,那么在这里使用std::unique_ptr。
【解决方案2】:

您正在向向量添加 instances 类。这导致slicing。

你需要做的是给行为实例添加指针,然后修改循环来做

(*myBehavior)->execute();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 2011-05-19
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多