具有迭代器和继承的STL容器

Mur*_*mal 2 c++ iterator stl object-slicing c++11

这是一个示例C++问题,以找出结果.

#include <iostream>
#include <vector>

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

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

protected:
    int m_n;
};

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

public:
    virtual int f() 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({ a, b });
    V::const_iterator i = y.begin();

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我预期的输出是"1 4 1 4",但正确的答案是"1 4 1 3".

从上面,

x[0]->f()
Run Code Online (Sandbox Code Playgroud)

即,x [0]只是指向类型A的对象的指针,并且调用f()返回1.

x[1]->f()
Run Code Online (Sandbox Code Playgroud)

即,x [1]只是指向A类对象的指针(指向派生类对象的基类指针),并调用返回(3 + 1)= 4的派生类f()

我不确定当我们将对象a和b添加到向量容器中并通过带继承的const_iterator迭代它们时这是如何表现的

i->f()
Run Code Online (Sandbox Code Playgroud)

我可以理解这一点,因为我只是指向第一个元素的指针,即对象a.

但这会发生什么?

(i + 1)->f()
Run Code Online (Sandbox Code Playgroud)

我的理解是它指向序列中的下一个元素,即对象b和通过派生类指针调用f()应该调用它的成员函数而不是基类1?

asc*_*ler 5

向量y包含两个类型的对象A.不打字B.当它被建造,它使副本ab,切片 b,因为它这样做.所以(i + 1)->f()调用A::f()A部分的副本b,给出3.