简体   繁体   English

虚函数:迭代向量 <Base Class> 用子类对象填充

[英]Virtual Functions: Iterating over a vector<Base Class> that is populated with subclass objects

Short Description: 简短的介绍:
I am iterating over a vector calling a virtual function on every object in the vector in order to execute a sequence of actions. 我正在迭代向量调用向量中的每个对象上的虚函数,以便执行一系列动作。 The vector is of the base class as is the iterator. 向量是基类,迭代器也是。 All the objects are children. 所有的对象都是孩子。 When the virtual function is called it executes the base class's function. 当调用虚函数时,它执行基类的函数。

(Really) Long Description: I am attempting to model a creature that has a set of behaviors. (真的)长描述:我试图模拟一个有一系列行为的生物。 My base class is abstract with only two functions (virtual) which all the subclasses have overridden: 我的基类是抽象的,只有两个函数(虚拟),所有子类都被覆盖了:

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


protected:
BEHAVIOR_TYPE m_Type;
};

I have created a number of children behaviors, such as move, consume, scout, etc. 我创造了许多孩子的行为,比如移动,消费,侦察等。

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;

};

I created a vector onto which I pushed instances of each Behavior subclass as well as an iterator to traverse it: 我创建了一个向量,我在其上推送了每个Behavior子类的实例以及遍历它的迭代器:

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

When the creature gets an action sequence, I try to iterate over the vector, dereference the iterator, and call the execute function: 当生物获得动作序列时,我尝试迭代向量,取消引用迭代器,并调用执行函数:

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

The problem is that it executes the parent's function rather than the child's function. 问题是它执行父函数而不是子函数。

In my understanding of late binding it should automatically call the appropriate function based on the type of object that was calling it rather than the type of pointer with which it was called, and in my code I anticipated it would be pointing to the child object. 在我对后期绑定的理解中,它应该根据调用它的对象的类型而不是调用它的指针类型自动调用适当的函数,并且在我的代码中我预计它会指向子对象。

Obviously I have made an error and somehow told the program that I want these to be treated as parents instead of children, but I cannot find my error. 显然我犯了一个错误,并以某种方式告诉程序我希望这些被视为父母而不是孩子,但我找不到我的错误。

A second symptom is that it will not let me make the parents function pure virtual, because it says it cannot instantiate an abstract class. 第二个症状是它不会让我让父项功能纯虚拟,因为它说它不能实例化一个抽象类。 I am not instantiating it explicitly anywhere in my code, but there must be somewhere I am doing it implicitly. 我没有在我的代码中的任何地方显式地实例化它,但必须有某个地方我隐式地这样做。 I cannot find where, however. 然而,我找不到哪里。 Certainly creating a vector to hold objects of the parent class does not require instantiating the parent, and that is the only time I reference the parent class directly. 当然,创建一个向量来保存父类的对象不需要实例化父对象,这是我唯一直接引用父类的时间。

Any help would be greatly appreciated. 任何帮助将不胜感激。

The class vector<Behavior> makes copies of whatever you store inside it, using the copy constructor Behavior::Behavior(const Behavior&); vector<Behavior>使用复制构造函数Behavior::Behavior(const Behavior&);存储在其中的任何内容的副本Behavior::Behavior(const Behavior&); . This destroys the polymorphism. 这破坏了多态性。 You need to use a pointer or smart pointer in the container instead: 您需要在容器中使用指针或智能指针:

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

If you don't have std::shared_ptr or std::tr1::shared_ptr in #include <memory> or similar, maybe you can use Boost's. 如果你没有#include <memory> std::shared_ptrstd::tr1::shared_ptr或类似的东西,也许你可以使用Boost。

You are adding instances of classes to the vector. 您正在向向量添加类的实例 This results in slicing . 这导致切片

What you need to do is add pointers to instances of behaviors, and modify the loop to do 您需要做的是添加指向行为实例的指针 ,并修改要执行的循环

(*myBehavior)->execute();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM