1

I am storing an objects with common parent in stl container (actually stack), but calling a virtual function on object inside of it results in calling an implementation in this common parent. See demo code:

#include <iostream>
#include <stack>

using namespace std;

class Z
{
        public:
                virtual void echo()
                {
                        cout << "this is Z\n";
                }
                int x;
};

class A: public Z
{
        public:
                virtual void echo()
                {
                        cout << "this is A\n";
                }
};

int main()
{
        A a;
        a.x = 0;
        Z z;
        z.x = 100;
        stack<Z> st;

        st.push(a);
        st.top().echo(); // prints "This is Z"
        cout << "x = " << st.top().x << endl; // prints 0

        st.push(z);
        st.top().echo();  // prints "This is Z"
        cout << "x = " << st.top().x << endl; // prints 100

        return 0;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
cdkrot
  • 279
  • 1
  • 2
  • 8

3 Answers3

2

In general, containers of objects and polymorphism don't mix : You are slicing your objects of type A into objects of type Z when you push them in the container (because the container is really expecting and storing objects of sizeof(Z))

Use std::stack<Z*>, or std::stack<std::unique_ptr<Z>> to manipulate pointers to your base class.


See also : What is the slicing problem in C++?

Community
  • 1
  • 1
quantdev
  • 23,517
  • 5
  • 55
  • 88
2

You have slicing:

You should use std::stack<Z*> or std::stack<std::unique_ptr<Z>>.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
2

What you observe is slicing. Your stack stores Z objects, so even if you construct an A object, it will not be stored in the stack - an Z object will be constructed from A and stored.

You cannot store in container by value if you want polymorphism. Use stack<unique_ptr<Z>>.

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51