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

Weird output for array used with polymorphism

本文关键字:数组 输出 多态性 一起      更新时间:2023-10-16

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

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

#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。因此,它似乎从S类中获取val成员,而不是每隔一个循环中的D类。但是为什么?

因为s++指针递增sizeof(S),而不是sizeof(D),但s实际上在运行时指向D数组。

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

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

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