John Tan
John Tan

Reputation: 1385

Calling derived class instances from a stack of a base class

Say I have an base struct Action:

struct Action
{
    int type;
    virtual void print() { }
}

And 2 derived structs A1, A2:

struct A1 : Action
{
    A1 : Action(0) { }
    void print() { cout << "A1"; }
}

struct A2 : Action
{
    A2 : Action(1) { }
    void print() { cout << "A2"; }
}

Then in my main function I have a stack:

stack<Action> actions;
A1 a1;
A2 a2;
actions.push(a1);
actions.push(a2);

while(!actions.empty())
{
    Action element = actions.top();
    element.print();
    actions.pop();
}

However, the print() function will always call the base class print(), instead of the derived class. How do I get it to refer to the derived class instead?

In C# I understand there is a GetType() function, but is there a similar thing in c++?

Edit: Specifically I am looking for a way to collect all objects of a similar base class into a single container, so that I can iterate through all of them, without losing information of a derived class.

Something along the lines of (in C#):

if(element.getType() == typeof(A1))
    ((A1)element).print();
else if (element.getType() == typeof(A2))
    ((A2)element).print();

Upvotes: 1

Views: 55

Answers (1)

amc176
amc176

Reputation: 1544

When you do actions.push(a1); and Action element = actions.top(); you are actually storing and getting copies of the actual Action that you want to store. To take advantage of virtual functions you need to access the members through pointers or references.

In your example, you would need to:

  1. Store pointers to your Actions

    stack<Action*> actions;
    A1 a1;
    A2 a2;
    actions.push(&a1);
    actions.push(&a2);
    
  2. Get those pointers and access print through them:

    while(!actions.empty())
    {
        Action* element = actions.top();
        element->print();
        actions.pop();
    }
    

    Live example.


It would be preferable to use a smart pointer like std::unique_ptr instead of a raw one but I omitted the details for the sake of simplicity.

Upvotes: 2

Related Questions