涉及多态的非常奇怪的错误?

时间:2016-02-22 04:26:37

标签: c++ oop

我有一个类,我们称之为A.它有一个名为myFunc的虚函数。

class A {
    public:
          virtual void myFunc(){}
}

然后我有一个派生类,称之为B。

class B: public A {
   public:
          void myFunc() {//does stuff}
}

然后我在另一个名为C的类中有一个函数,它接受一个A的数组。这个数组实际上不是A类,它实际上由B或从A派生的另一个类的元素组成。

class C {
    private:
           void anotherFunc(A myArray[], int index) {
                myArray[index].myFunc();
           }
}

我基本上希望调用myFunc,除了myArray实际派生类实现的版本,而不是A实现的版本。

如果索引为0,这可以正常工作。但由于某种原因,如果它是0以外的任何索引,它会崩溃并出现段错误(EXC_BAD_ACCESS)。

所以我尝试了以下内容:

1)我使用调试器在anotherFunc中设置断点。出于某种原因,myArray只被视为大小为1的数组,其他元素由于某种原因不会出现。

2)但是如果我将myArray上调用的函数从myFunc更改为非虚拟的其他函数,它适用于所有索引......

知道发生了什么事吗?

编辑:这就是调用anotherFunc的方式。

B myArray[7];
//Initialize elements
anotherFunc(myArray, 2);

1 个答案:

答案 0 :(得分:7)

  

这个数组实际上不是A类,它实际上由B或从A派生的另一个类的元素组成。

A myArray[](实际上读取A *myArray,因为它是一个函数参数),指向一个A个对象的数组。阵列是同质的,即所有元素必须是相同类型的。

您的函数需要一个由A个对象组成的数组。但是,您的代码提供了一个由B个对象组成的数组。一旦访问超出数组的第一个元素,事情就会变成蛋羹,因为AB个对象具有不同的大小。例如,当编译器计算出要访问myArray[1]的内存地址时,它将通过第一个B对象的部分地址结束;不是第二个B对象的地址。

要解决此问题,您需要使函数接受B *,或使用其他容器。