Henry Henrinson
Henry Henrinson

Reputation: 5392

Virtual methods not acting virtual

Consider the folowing code:

#include<iostream>
#include<vector>

class A
{
public:
    A(int n = 0) : m_n(n) {}

public: 
    virtual int value() const {return m_n;}
    virtual ~A() {}

protected:
    int m_n;
};

class B : public A
{
public:
    B(int n = 0) : A(n){}

public:
    virtual int value() const {return m_n + 1;}
};

int main(char* args[])
{
    const A a(1);
    const B b(3);
    const A *x[2] = {&a, &b};
    typedef std::vector<A> V;
    V y;
    y.push_back(a);
    y.push_back(b);
    V::const_iterator i = y.begin();

    std::cout << x[0]->value() << x[1]->value()
        << i->value() << (i+1)->value() << std::endl;

    getchar();
    return 0;
}

Why does that print out 1413, rather than 1414? I would expect value() to behave as a virtual function even when called like (i+1)->value();.

Upvotes: 3

Views: 101

Answers (2)

Bartek Banachewicz
Bartek Banachewicz

Reputation: 39370

Because when you do y.push_back(b); slicing happens; the vector holds objects of type A. To make use of polymorphism, you need references or pointers.

Upvotes: 3

juanchopanza
juanchopanza

Reputation: 227370

Your vector V holds A objects, so there is no scope for dynamic dispatch. You are always calling A::value(). The B part of your objects is sliced away when they are copied into the vector. It is the same as doing this:

B b(1);

A a1 = b;  // a1 is an A object, not a B.
a1.value();

See object slicing.

Upvotes: 5

Related Questions