运行时多态性 - 箭头运算符访问错误的成员?

Runtime Polymorphism - Arrow operator accessing the wrong member?

我的程序中有以下 classes:

class base {
public:
    int bval;
    base() {
        bval = 1;
    }
};

class deri: public base {
    int dval;
public:
    deri() {
        dval = 2;
    }
};

还有一个函数f,它接受指向classbase对象的指针和它指向的数组大小:

void f(base *arr, int size) {
    for(int i=0; i<size; i++, arr++){
        cout << arr->bval << " ";
    }
    cout << endl;
}

这是主要的:

int main() {
    base a[5];
    f(a, 5); // first call

    deri b[5];
    f(b, 5); // second call
}

第一次调用的输出是 1 1 1 1 1,这是正确的。

但是第二次调用的输出是1 2 1 2 1,这让我很意外。对于函数 f.

中的 for 循环的每第二次迭代,似乎 dval 的值正在代替 bval 打印

此外,如果我在 class deri 中包含另一个私有数据成员 int dval2,则每次执行时第二次调用的输出都是 1 2 65535 1 2(所以 65535看起来不像任何随机值)。

为什么箭头运算符表现出这种行为

您将指针作为指向 f()base 指针传递,因此指针算法不适合您的 deri 数组。

此时:for(int i=0; i<size; i++, arr++),只将base的大小加到arr,因为arr是一个base指针

在这种情况下,真正存储的是什么类型的对象并不重要;增加指针值时不会查看它们。

两个有用的选项:

  1. 使用 C++ 容器。例如。 std::vector<deri> b(5)void f(const std::vector<deri> &vec).
  2. 传递一个指针数组。在这种情况下,当使用箭头运算符访问指针时,可以发生多态性。请注意,您的基础 class 需要一个 vtable,您将通过定义和声明一个虚拟析构函数来获得它(不需要 vtable 来提供预期的输出,但出于其他几个原因)。