2013-08-10 3 views
0

Может кто-то пожалуйста, объясните, почему i->value() и (i + 1)->value() печатает 1 и 3 не 1 и 4, как x[0]->value() << x[1]->value()Векторный контейнер и статическое связывание в 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); //a.m_n=1 
    const B b(3); //b.m_n=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; 

    return 0; 
} 

Спасибо

+4

Бьярне Страуструп говорит, если вы знаете * * триумфатор, вы также знаете, C++. Они лучшие друзья, и они всегда бродят вместе. – Nawaz

ответ

5

y.push_back(b); создает экземпляр A, который является копией A подобъекте в b, и толкает это на вектор. На векторе нет экземпляров B, и не может быть, поэтому B::value() не вызывается. Читайте о object slicing

+1

Напротив, при создании 'x' не происходит среза, потому что' x' содержит указатели или ссылки (в данном случае указатели) на объекты класса 'A'. – Oswald

3
void push_back (const value_type& val); 

создаст A копию val если вектор определяется как std::vector<A> V. Вы видите здесь так называемый slicing problem. Вот почему вы должны использовать

std::vector<A*> V 

или

std::vector<shared_ptr<A> > V