Search code examples
c++inheritancepolymorphismvirtualfunction-calls

Polymorphism Trouble in C++


I'm trying to access a data member of a derived class through its base class and I'm having some trouble.

Here is the code:

for (auto actor : drawables) {
    if (actor.isDrawable()) {
        std::vector<glm::vec3> verts = actor.getVerticies();
        for (glm::vec3 v : verts) {
            // do stuff
        }
    }
}

But when I try to run this, it says that verts has a size of 0 when I know I have added vec3's into the vector.

I have a base class called Actor3D that has the following properties:

    class Actor3D
    {
    private:
    static int actorCount;

    protected:
    int id;
    bool _isDrawable;

    glm::vec3 position;
    glm::vec3 rotation;

    std::vector<glm::vec3> verts;
    //std::vector<glm::vec3> color;
    std::vector<glm::vec3> normals;

    virtual void addVert(float x, float y, float z);

    public:
    virtual std::vector<glm::vec3> getVerticies() const { return verts; }
    ...
    }

And then I have a derived class with the following definition:

    #include "engine\Actor3D.h"

    class Cube : public Actor3D
    {
    public:
    Cube();
    ~Cube();
    };

In the cpp file:

    Cube::Cube()
    {
    _isDrawable = true;

    position.x = 5;
    position.y = 5;
    position.z = 7;

    addVert(-1.0, 0.0, -1.0);
    addVert(-1.0, 0.0, 1.0);
    addVert(1.0, 0.0, 1.0);
    addVert(1.0, 0.0, -1.0);
    }

    Cube::~Cube()
    {
    }

Is there some way I can access the verts vector through the base class in my for loop?


Solution

  • The code seems correct, but you don't show you how are populating drawables and the body of addVert. If you could provide a small example that we could compile and run that would be better. It should not be hard for this use case.

    Note that you don't need to define the methods as virtual, unless you modify their behavior in the derived class, but it should not be the case for these ones.

    Also getVerticies() (should be getVertices()) returns a copy of your vector, it may not be intended.

    When you write for (auto actor : drawables) you are copying actor and all its content, it is probably not what you meant, I would write for (auto const &actor : drawables)

    Do you also know about slicing? If your drawables is declared as std::vector<Actor3d> it contains only the Base class and not the derived! Right now your code should work if you create a cube and add it to drawables, because your example does not use anything specific to Cube.

    Again if you provide a small reproducible case it will be easier. With a link to http://ideone.com/sphere-engine it would be perfect :)