继承示例没有打印预期的结果

inheritance example not printing expected results

本文关键字:结果 打印 继承      更新时间:2023-10-16

尝试记住基本的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;
}

数组和多态性不能在c++中混合使用。

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

你的init方法是在Base对象中切片Derived对象。下面的赋值有未定义的行为,它在Derived对象的某个地方设置了一些字节。

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

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

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

原因很简单:当你做一个像array[i]这样的操作时,编译器会把它翻译成*(array + i),而内部地址算术是像array + sizeof(T) * i这样做的,其中Tarray的静态类型。现在,对于从基类型B派生的类型D,它通常保持sizeof(B) < sizeof(D)。因此,如果将派生对象的数组视为基于对象的数组,则索引算法最终将访问对象中或多或少随机位置的元素。