与多态性一起使用的数组的奇怪输出

时间:2013-01-25 17:48:33

标签: c++ arrays

  

可能重复:
  Can a pointer to base point to an array of derived objects?

我正在练习所学的知识,并尝试了以下内容:

#include <iostream>

struct S {
    S() : val(0) {}

    int val;
};

struct D : S {
    D() : val(1) {}

    int val;
};

void f(S *s) {
    for (int i = 0; i < 5; i++, s++)
        std::cout << s->val;
}

int main() {
    D d[5];
    f(d);
}

我觉得奇怪的是输出是01010而不是11111,就像我预期的那样。所以它似乎是从val类中获取S成员而不是在每个其他循环上获得D类。但为什么呢?

1 个答案:

答案 0 :(得分:6)

由于s++使指针增加sizeof(S),而不是sizeof(D),但s实际上在运行时指向D数组。 / p>

  • 第一次迭代恰好与第一个数组元素的S::val对齐(为0),
  • 第二个第一个元素的D::val(即1),
  • 第三个元素与第二个元素的S::val(为0)
  • 等......

这实际上是一种未定义的行为。如果您的课程看起来不同(或者使用了具有不同对齐方式的平台),您将收到不同甚至更令人困惑的结果。

如果您不需要多态,只需声明该函数以接收D(不是S)的数组。如果确实需要多态性,则应考虑使用(智能)指针数组,而不是具体元素数组(并通过虚函数而不是直接字段访问来访问数据)。