Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does polymorphism work in C++ without pointers / references? [duplicate]

Possible Duplicate:
Virtual Functions Object Slicing

let's consider:

#include <vector>
#include <iostream>
using namespace std;

struct A {
    virtual void do_it() { cout << "A" << endl; } 
};

struct B : public A {
    virtual void do_it()  { cout << "B" << endl; } 
};

int main() {
    vector<A> v;
    v.push_back(B());
    v[0].do_it(); // output is A
}

which function will be called? Basically is it possible to use polymorphism without pointers if no slicing is present?

like image 748
lezebulon Avatar asked Jul 26 '12 13:07

lezebulon


2 Answers

No it will not be possible without pointers.

Since you create an object B and push it to the vector containing A, it will get copied (sent to the copy constructor of A) and an instance of A will be added to the vector. I.e. the object will be sliced.

Given this code:

struct A {
        virtual void d() { 
            std::cout << "Hello A" << std::endl; 
        } 
};

struct B : public A {
        virtual void d() { 
            std::cout << "Hello B" << std::endl; 
        } 
};

int main() {
        std::vector<A> v;
        v.push_back(B());
        v[0].d();
}

The output will be:

Hello A
like image 94
Man of One Way Avatar answered Sep 28 '22 13:09

Man of One Way


The problem is that in your example there is actually slicing. Using push_back is somehow equivalent to:

A array[N];
array[last++] = B();

In the second line is where you have the slicing, since each position in the array can hold an object from type A but not one from type B.

You could use pointers to solve this problem, defining v as std::vector<A*> v. Probably better, you could use smart pointers (either the ones present in C++11 or the ones in Boost).

like image 41
betabandido Avatar answered Sep 28 '22 13:09

betabandido