2

I have the following piece of code (#includes and using namespace std omitted):

class A {
    public:
        void call(){callme();}
    private:
        virtual void callme() {cout << "I'm A" << endl;}
};

class B : public A {
    private:
        virtual void callme() {cout << "I'm B" << endl;}
};

class C : public B {
    public:
        virtual void callme(){ cout << "I'm C" << endl;}
};

int main(){
    vector<A> stuff = {
        A(), B(), C(),
    };
    stuff[0].call(); // output: I'm A
    stuff[1].call(); // output: I'm A
    stuff[2].call(); // output: I'm A
    return 0;
}

As stated in the comments, the output of the above program is:

I'm A
I'm A
I'm A

However, I would like that C++ automatically recognizes the type with which the corresponding element was created. I.e. I would like that C++ outputs

I'm A
I'm B
I'm C

(That is, the compiler shall pick the proper subclass for me.)

Is this possible in this scenario (i.e. if all the elements come out of a vector)?

phimuemue
  • 34,669
  • 9
  • 84
  • 115
  • 5
    See: [What is the slicing problem?](http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c) – jrok Jun 25 '13 at 14:08

2 Answers2

2

Member functions virtuality works only when you call them from pointer to the actual object, not from an object itself, because in your example objects were automatically statically upcasted to class A. Change your code to:

std::vector<std::unique_ptr<A>> stuff = {
    std::unique_ptr<A>(new A()), 
    std::unique_ptr<A>(new B()), 
    std::unique_ptr<A>(new C()),
};
stuff[0]->call(); 
stuff[1]->call(); 
stuff[2]->call();
sasha.sochka
  • 14,395
  • 10
  • 44
  • 68
1

For C++ Polymorphism, you should use either pointer or reference. You could do like this

int main(){
         vector<A*> stuff;
         stuff.push_back(new A);
         stuff.push_back(new B);
         stuff.push_back(new C);
         stuff[0]->call(); // output: I'm A
         stuff[1]->call(); // output: I'm A
         stuff[2]->call(); // output: I'm A
         while (!stuff.empty()){
                 delete stuff.back();
                 stuff.pop_back();
         }
         return 0;
 }

Reference: http://www.cplusplus.com/doc/tutorial/polymorphism/

ioeric
  • 155
  • 3
  • 11