简体   繁体   中英

Misunderstood the virtual functions work in vector

I have following code on c++:

#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()
{
    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;

    system("PAUSE");

    return 0;
}

The compiler returned result: 1413.

I am little bit confused, because I thought the right result would be 1414 (as the function virtual). How do you explain this program behavior?

You are slicing the object, in order to get polymorphism you need to use either a pointer or a reference . This example keeping as close as possible to your original example and using a pointer will act as you wanted:

const A a(1);
const B b(3);

typedef std::vector<const A*> V;
V y;
y.push_back(&a);
y.push_back(&b);
V::iterator i = y.begin();

std::cout << (*i)->value()  << std::endl ;
++i ;
std::cout << (*i)->value()  << std::endl ;

To show briefly how the object slicing works here:

const A a(1);
const B b(3);
std::vector<A> y; // so y contains objects of type A

y.push_back(a);   // y[0] is copy-constructed from a
y.push_back(b);   // y[1] is copy-constructed from b

Note that in both push_back calls, it's always an A being constructed, via the automatically-generated A::A(const A&) copy constructor.

Note also that a B is-a A , which is to say b can be implicitly cast to an A and passed into the same copy-constructor.

So, y[1] is an instance of A with the m_n value copied from b , but its virtual function is still A::value . If you have constructor B::B modify the value when it is initialized, instead of when it is returned, you'll see the result you expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM