c++ - 具有迭代器和继承的 STL 容器

标签 c++ c++11 stl iterator object-slicing

这里是一个示例 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;
}

我期望的输出是“1 4 1 4”,但正确答案是“1 4 1 3”。

从上面看,

x[0]->f()

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

x[1]->f()

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

我不确定当我们将对象 a 和 b 添加到 vector 容器中并通过继承的 const_iterator 迭代它们时,其行为如何

i->f()

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

但是这里会发生什么呢?

(i + 1)->f()

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

最佳答案

vector y包含两个A类型的对象。不输入 B。当它被构造时,它会复制abslicing b 就是这样做的。因此,(i + 1)->f()A 部分的拷贝上调用 A::f() b,给出 3。

关于c++ - 具有迭代器和继承的 STL 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35421688/

相关文章:

c++ - 如何一一删除STL deque的所有元素?

c++ - 作为返回值的 STL 迭代器

c++ - 有人可以解释这个 C++ 程序的输出吗?

c++ - 运算符 << - 参数评估的顺序

c++ - 删除调用内存集?

c++ - 如何找到最小第一个索引的 vector<vector<int>> 的所有索引

C++ header-only 库避免 "using namespace"污染

c++ - 基于范围的 for 循环,使用指向字符串的指针

c++ - 从模板模板方法参数中获取类型

c++ - 如何在 vector 销毁时释放其内容?