C++: Calling the virtual function of the derived class
Asked Answered
N

3

5

Suppose I have a class with a virtual function and a derived class that implements the virtual function in a different way. Suppose I also have a vector of the base class used to store derived classes. How would I execute the virtual function of a derived class in the vector without knowing in advance what the derived class is? Minimal code that illustrates the problem:

#include <iostream>
#include <vector>

class Foo {
public:
    virtual void do_stuff (void) {
        std::cout << "Foo\n";
    }
};

class Bar: public Foo {
public:
    void do_stuff (void) {
        std::cout << "Bar\n";
    }
};

int main (void) {
    std::vector <Foo> foo_vector;
    Bar bar;

    foo_vector.resize (1);
    foo_vector [0] = bar;

    bar.do_stuff ();            /* prints Bar */
    foo_vector [0].do_stuff (); /* prints Foo; should print Bar */
    return 0;
}
Neibart answered 5/6, 2011 at 0:19 Comment(1)
Perhaps using std::vector<Foo*> (by pointer, or by reference), to avoid object slicing? Otherwise, the moment you assign bar object to the vector, it has been sliced (a new Foo is created and stored in the vector, instead of your bar), which is probably not what you want. Using pointer will make code more complicated, though.Erkan
S
14

You can't. The objects in the vector will have been sliced -- any derived-class instance data will have been chopped off, so calling the method would be a super-bad idea.

If, on the other hand, you have a vector of pointers to base, then you simply call the virtual method, and the derived-class version will be invoked.

Seppala answered 5/6, 2011 at 0:22 Comment(1)
Thank you. I was unaware of slicing, and your suggestion solved the problem.Neibart
M
2

The class that you are actually calling is not a class of Bar, but instead a class of Foo. What you are doing at foo_vector [0] = bar; is a call of the implicit operator= which is doing its best to make something smart happen. The memory space is still the size of a Foo though, so it can't ever be a Bar.

Myopic answered 5/6, 2011 at 0:57 Comment(0)
B
0

When using virtual functions , you make use of pointers to objects. This way the exact function is called during run time ("How would I execute the virtual function of a derived class in the vector without knowing in advance what the derived class is?" What you mean here probably is "run time").

The use of marking a function as virtual is that, you ask the compiler to postpone or figure out the "TYPE" of an object calling that function at run time rather than the usual way "compile time" . This is achieved by using pointers to objects. So to put it in a simple line "Use pointers to objects to make use of Virtual functions".

Bushnell answered 5/6, 2011 at 4:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.