0

我的程序中有以下课程:

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

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

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

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,这对我来说是非常出乎意料的。似乎 的值dval被打印出来,而不是函数内循环bval的每第二次迭代。forf

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

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

4

1 回答 1

4

您将指针作为指向 的base指针传递f(),因此指针算术不适合您的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. 传递一个指针数组。在这种情况下,当使用箭头运算符访问指针时,可能会发生多态性。请注意,您的基类需要一个vtable,您将通过定义和声明一个虚拟析构函数来获得它(不需要 vtable 来提供预期的输出,但出于其他几个原因)。
于 2020-05-18T08:09:10.423 回答