Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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).

Does polymorphism work in C++ without pointers / references?

Yes and no.

Dynamic polymorphism works in C++ when the static type of a pointer or reference might be different to the dynamic type of the object it refers to, and behaviour is chosen based on the dynamic type. This requires pointers or references, since the object itself has only one type.

Static polymorphism, using templates, works perfectly with objects, but solves a different class of problem. Your example requires dynamic polymorphism, to choose behaviour based on the run-time type of the objects.

which function will be called?

The vector contains objects of type A, so A::do_it() will be called. The object has no knowledge that it was created by slicing an object of type B.

Basically is it possible to use polymorphism without pointers if no slicing is present?

Slicing is always present when you create base-class objects from derived-class objects. That is the definition of slicing.

Does polymorphism work in C++ without pointers / references?

Yes. See static polymorphism.

In your case, the base function will be called, but saying polymorphism doesn't work is wrong. Polymorphism is guaranteed to work, it's just that you're not taking advantage of it. What you have is basically a collection of A objects.

This will not work, since sizeof(parent) will not always equal sizeof(child)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top