0

I have a few classes, ObjDef, PeopDef, NpcDef, and PlyDef, such that PlyDef and NpcDef each seperately inherit PeopDef, and PeopDef inherits ObjDef. Each class has functionality that builds on the class before it, so it's important that PeopDef::Tick is called before ObjDef::Tick. I have every object stored in a vector<ObjDef> object, but when the main tick loop goes through them, I want them to call the original classes' Tick, rather than ObjDef::Tick, which is what the vector<ObjDef> currently makes it do. Is there any way to do this, or do I have to have a separate vector for each class?

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158

1 Answers1

2

You can store an ObjDef pointer (ObjDef* or a smart pointer) in the vector and make the Tick method virtual.

Here's an example:

#include <iostream>
#include <vector>
#include <memory>

class ObjDef
{
public:
    virtual void Tick()
    {
        std::cout << "ObjDef::Tick\n";
    }
};

class PeopDef : public ObjDef
{
public:
    virtual void Tick()
    {
        std::cout << "PeopDef::Tick\n";
    }
};

int main()
{
    std::vector<std::shared_ptr<ObjDef>> objects;

    std::shared_ptr<ObjDef> obj(new ObjDef());
    std::shared_ptr<ObjDef> peop(new PeopDef());

    objects.push_back(obj);
    objects.push_back(peop);

    for (auto object : objects)
    {
        object->Tick();
    }

    return 0;
}
  • 1
    Depending upon object lifetime and memory management, it might be better to use `std::shared_ptr` isntead. – Robᵩ Sep 12 '13 at 03:59
  • Making the shared functions like `::Init` and `::Tick` virtual changed nothing, it still used the `ObjDef` functions. Changing `vector` to `vector` makes around 40 "expression must have class type" errors. – Nihil K'ri Sep 12 '13 at 05:01
  • 1
    I'd have to see more code to know what those errors are about, but I've added a quick example. – Isaac McGarvey Sep 12 '13 at 09:02
  • 2
    Although it isn't required here (because of `shared_ptr`), it's generally a good idea to define a `virtual` dtor if a class is intended to be stored via a base class pointer. (Actually, it's generally a good idea if the class is intended to be inherited from.) – dyp Sep 12 '13 at 09:17
  • I would recommend `std::unique_ptr` over `std::shared_ptr`. The latter adds unnecessary overhead. – Mooing Duck Sep 12 '13 at 23:53