Calling derived class functions from within a vect

2019-03-31 00:42发布

问题:

I have two classes:

class Object {
public:
  Object();
  virtual void update();
  virtual void draw();

private:

protected:
  int x, y, tick;

}

and

class Unit : public Object {
public:
  Unit();
  void update();

private:

protected:

}

I then define the constructors and functions in sepparate .cpp files.

Here's the definitions for Object:

Object::Object() {
  x = y = 0;
};

Object::update() {
  tick ++;
};

Object::draw() {
  // All my draw code is in here.
};

And Unit:

Unit::Unit() : Object() {

};

Unit::update() {
  Object::update();
  // Then there's a bunch of movement related code here.
};

Everything works fine individually, but I run into a problem when trying to call functions from within a vector.

vector<Object> objects;

I then do this in my void main():

for (int i = 0; i < objects.size(); i ++) {
  objects[i].update();
  objects[i].draw();
};

This draws everything fine, but it only calls the Object verson of update() not the version as defined by the derived class. Do I have to make a vector for each type that I derive from the Object class for it to work, or is there another way to call the derived functions?

Thanks in advance - Seymore

回答1:

Yes, it calls methods of class Object, because you have a vector of class Object objects:

vector<Object> objects; // stores instances of class Object

The possible solution is to use a vector of pointers:

vector<Object*> objects;
objects.push_back( new Unit() );

and then call though pointers:

for (int i = 0; i < objects.size(); i ++) {
    objects[i]->update();
    objects[i]->draw();
}


回答2:

If you want to use object oriented polymorphism in C++ (with the meaning : you have a base class and derived classes and at runtime you can come across any off those) you must use pointers.

vector<Object *> objects;

That means manual memory management (but you can use shared_pointers or http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/ptr_container.html), and possibly a very slight loss of performance (because of one extra dereferencing and v-table, however you shouldn't really care about it). And don't forget to make your methods virtual ;)

I think this is why I rarely use on my daily work object oriented programming as I learned it at school ;) I use heritage, but don't mix mother and daugther classes in the same containers (and I use templates for many interfaces).