1

可能重复:
指向基点的指针可以指向派生对象数组吗?

我正在练习学到的东西,我尝试了以下方法:

#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成员,而不是在每个其他循环中获取类。但为什么?SD

4

1 回答 1

6

因为s++将指针增加sizeof(S), not sizeof(D),但实际上在运行时s指向数组。D

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

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

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

于 2013-01-25T18:03:23.403 回答