【问题标题】:Weird output for array used with polymorphism [duplicate]与多态一起使用的数组的奇怪输出[重复]
【发布时间】:2013-01-25 17:48:33
【问题描述】:

可能重复:
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。所以它似乎是从S 类中获取val 成员,而不是在每个其他循环上的D 类。但为什么呢?

【问题讨论】:

  • 顺便说一句,f(s); 应该是f(d);,对吧?

标签: c++ arrays


【解决方案1】:

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

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

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

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

【讨论】:

  • 很好的答案!但为什么这是未定义的行为?
  • @David 不幸的是,我不是标准的窥视者,所以我无法指出 C++ 标准中定义这一点的确切段落(我确信它就在那里!)。从逻辑上讲(并且独立于 C++),值数组不是 covariant,只有引用数组是。
猜你喜欢
  • 1970-01-01
  • 2016-12-21
  • 1970-01-01
  • 2023-03-05
  • 2018-09-12
  • 2015-12-29
  • 2012-01-23
  • 2019-03-27
  • 1970-01-01
相关资源
最近更新 更多