继承示例不打印预期结果

时间:2014-06-14 21:43:36

标签: c++ inheritance

尝试记住基本的C ++内容(它已经很长时间了),并且正在使用编译器。我创建了一个简单的基/子继承示例。

我希望下面输出

index 0 is 0
index 1 is 1
index 2 is 2

但是得到:

index 0 is 0
index 1 is 2
index 2 is 0

有人可以指出我的错误显然是什么错误吗?

#include <cstdlib>
#include <iostream>

#include <stdio.h>
#include <string>
using namespace std;

class Base
{
public: 
    Base(){x=0;}
    int x;
};
class Derived : public Base
{
public:
    Derived() { y=0;}
    int y;
};

// practicing operator definition syntax
ostream& operator<<(ostream& ostr, const Base& base)
{
       ostr << base.x << endl;
       ostr << flush;
    return ostr;
}

void init(Base *b)
{
    for (int i = 0; i<3; i++)
    {
        b[i].x=i; 
    }
};

int main(int argc, char** argv)
{
    Derived arr[3];
    init(arr);
    for (int idx = 0; idx< 3; idx++)
    {
        cout << "index is " << idx << ' ' << arr[idx] << endl;
    }

    return 0;
}

2 个答案:

答案 0 :(得分:5)

数组和多态不会在C ++中混合。

DerivedBase个对象具有不同的大小,程序中涉及的任何指针算法都将失败。

您的init方法正在对Derived个对象中的Base个对象进行切片。以下赋值具有未定义的行为,它在Derived对象的某处设置了一些字节。

考虑使用std::vector<std::unique_ptr<B>>作为替代。

此外,您的Base类缺少其虚拟析构函数,稍后会调用更多未定义的行为。

答案 1 :(得分:4)

派生类型的数组不是基类型的数组!虽然指向派生对象的指针转换为指向基础对象的指针,但是不能将基指针用作指向基础对象数组的指针。

推理非常简单:当您执行array[i]之类的操作时,编译器会将其转换为*(array + i),内部地址算术将完成array + sizeof(T) * i T之类的操作。 }是array的静态类型。现在,对于从基类型D派生的类型B,它通常保留sizeof(B) < sizeof(D)。因此,如果将派生对象数组视为基于对象的数组,则索引算法将最终访问对象中或多或少随机位置的元素。