Home > Blockchain >  Member values not accessed in vector of instances of different subclasses
Member values not accessed in vector of instances of different subclasses

Time:03-27

Jumping off of the above question Making a vector of instances of different subclasses : when implementing a vector of (pointers to) different subclasses (initialized as vector<Base*> objects), I expect to be able to access the correct member variables based on the subclass called.

Below is sample code:

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

using namespace std;

class Entity {
public:

    int index;
    Entity() {};
    virtual ~Entity() {};
    virtual void hit() = 0;
};
class Mesh : public Entity {

public:
    int index;
    Mesh(int x) {this->index=x;};
    virtual void hit() {}
};

int main() {
    vector<unique_ptr<Entity>> objects;
    objects.push_back(unique_ptr<Entity>(new Mesh(35)));
    objects.push_back(unique_ptr<Entity>(new Mesh(10)));

    for ( int i = 0 ; i < objects.size() ; i   )
        cout << objects[i]->index << endl;

    return 0;
}                                                                                                                                                                          

Where I expect

35
10

to be printed, meanwhile I get instead.

0
0

How can I access the correct member variable values in this scenario?

CodePudding user response:

The problem is due to a misunderstanding on inheritance. If you redefine your Mesh as follows, it would work as expected:

class Mesh : public Entity {

public:              
    //int index;     // No don't redefine:  here you'd have two different indexes 
    Mesh(int x) {this->index=x;};
    void hit() override {}   // extraa safety: use override instead of virtual to be sure to override
}; 

Online demo

Not related to the problem, but some more thoughts:

  • You can of course only use the interface of the base class (here Entity).
  • It is not very prudent to expose the index member publicly. A safer option would be to have it private, and access it via a public getter. If the index should be set only at construction, the Entity constructor should take care of it, otherwise you could consider a public setter.
  • Related