0

Is it possible to access the members of a child class when looping though a vector?

struct Object
{
    std::string name;
};

struct Rect : Object
{
    int x;
    int y;
    int width;
    int height;
};

struct Circle : Object
{
    int x;
    int y;
    int radius;
}

Running the code below gives me the error struct Object has no member named 'x' which I'm guessing is because auto& sees it as an Object. Is there any way for the iterator to use the Rect members?

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

    Rect r;
    r.name = "test";
    r.x = 1;
    r.y = 1;

    objects.push_back(r);

    for(auto& ob: objects)
    {
        std::cout << ob.x << std::endl;
    }

    return 0;
}
fatnic
  • 499
  • 6
  • 12
  • 2
    Read about [*object slicing*](https://en.wikipedia.org/wiki/Object_slicing). – Some programmer dude Aug 18 '15 at 13:15
  • Firstly, your `Rect` is being sliced when you copy it into the `std::vector`, so it is not a `Rect`. Secondly, the compiler can't know that a given `Object` is a `Rect`, so you'll need to `dynamic_cast` or similar. – TartanLlama Aug 18 '15 at 13:15

2 Answers2

1

Yes, it's possible, auto is just syntactic sugar. However, in your example, you are looping over the vector of Objects, so

for(auto& ob: objects)
{
    std::cout << ob.x << std::endl;
}

is the same as

for(Object& ob: objects)
{
    std::cout << ob.x << std::endl;
}

Your Object class does not have the x member (your Rect class, which is derived from Object, does), hence the error (you are experiencing object slicing).

Community
  • 1
  • 1
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
1

C++ standard containers contains objects and not references as in other languages. That means that when you store a object for a subclass in the container, you just store an object obtained by the copy constructor (or the operator = depending of method used). So you only store a base class object that have neither the fields nor the methods from the subclass. This is called object slicing as said by Joachim Pileborg in its comment.

If you want to store subclass objects, you will have to use pointers (preferently unique_ptr or shared_ptr instead of raw pointers unless you have good reasons to use the latter)

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252