【问题标题】:inheritance example not printing expected results继承示例不打印预期结果
【发布时间】:2014-06-14 21:43:35
【问题描述】:

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

【问题讨论】:

  • 你要传递什么给init
  • 显然是错误的事情(见下面的回复)

标签: c++ inheritance


【解决方案1】:

数组和多态不能在 C++ 中混用。

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

您的 init 方法是在 Base 对象中分割 Derived 对象。以下分配具有未定义的行为,它在 Derived 对象的某处设置了一些字节。

考虑使用std::vector&lt;std::unique_ptr&lt;B&gt;&gt; 作为替代。

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

【讨论】:

  • +1 虽然缺少虚拟析构函数在这里不是问题。
  • “数组和多态性不能混合......”。我不知道这一点。我认为由于数组只是指向数组中第一个对象的指针,这类似于声明: Base* b = new Derived[3];啊....是的,你们都是对的。感谢您唤醒早已死去的脑细胞! :-)
【解决方案2】:

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

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

【讨论】:

  • 是的,准确。谢谢。
猜你喜欢
  • 1970-01-01
  • 2014-07-28
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
相关资源
最近更新 更多