【问题标题】:Polymorphism & Pointers to arrays [duplicate]多态性和指向数组的指针[重复]
【发布时间】:2010-11-27 13:33:32
【问题描述】:

我有一个 A 类:

class A
{
    public:
        virtual double getValue() = 0;
}

还有一个B类:

class B : public A
{
    public:
        virtual double getValue() { return 0.0; }
}

然后在 main() 我做:

A * var;
var = new B[100];
std::cout << var[0].getValue(); //This works fine
std::cout << var[1].getValue(); //This, or any other index besides 0, causes the program to quit

如果我这样做:

B * var;
var = new B[100];
std::cout << var[0].getValue(); //This works fine
std::cout << var[1].getValue(); //Everything else works fine too

一切都编译得很好,但似乎我的多态性可能有问题?我很困惑。

【问题讨论】:

    标签: c++ arrays polymorphism pointers


    【解决方案1】:

    您不能以多态方式处理数组,因此 new B[100] 创建一个由 B 对象组成的数组并返回一个指向该数组的指针 - 或等效于数组的第一个元素 - 虽然分配此指针是有效的指向基类的指针,将其视为指向A 对象数组的指针是无效的。

    您不能这样做的主要原因是(通常)派生对象与其基类的大小不同,因此尝试将数组作为基类对象数组访问将不会使用正确的偏移量来获取指针到派生类数组的下一个成员的下一个基类子对象。

    【讨论】:

    • @Charles 我假设如果他将他的数组更改为 A ** var 那么这个限制将不适用(并通过新的所有 100 个项目正确初始化它)
    • 啊,我明白了。所以我想创建一个包含 100 个指向 A 的指针的数组,对吧?
    • @Glen:不太清楚你在做什么。你会有一个指针数组,而不是一个对象数组。因为指针不是从其他指针派生的,所以不会出现问题。
    • @查尔斯。如果他有一个指向 A 的指针数组,那么他可以做 var[i] = new B();然后调用 var[i]->getValue() 和 B::getValue() 将被正确调用
    • @Glen:嗯,是的,它可以工作,但现在他必须手动分配 100 个对象,并在某个时候释放它们。就个人而言,我会选择对象数组(或者更可能我会使用std::vector&lt;B&gt;)。
    【解决方案2】:

    多态性没有问题,但处理记忆的方式有问题。 [] 运算符将在第一种情况下按 sizeof(A) 字节和在第二种情况下按 sizeof(B) 字节推进数组。因为对象属于 B 类型,所以 A* 没有指向内存中的正确位置。

    这是另一种看待它的方式

    char * var;
    var = (char*) new B[100];
    std::cout << ((A*)var[0]).getValue(); //This works fine
    std::cout << ((A*)var[1]).getValue(); //This will fail
    std::cout << ((A*)var[sizeof(B)]).getValue(); // should work
    

    【讨论】:

      【解决方案3】:

      你没有分配数组中的对象:

      for (int i=0;i<100;i++)
        var[i] = new B;
      

      (虽然我可能混淆了 C++ 和 C#)

      【讨论】:

      • 不要认为这是正确的。它是 B 对象的数组,而不是 B 对象的指针数组。
      • var 是指针变量,而不是指向指针的指针,因此var[i] = new B 无效(除非有一个异常定义的赋值运算符获取指针)。
      • 这是不正确的。 char * c = new char[100]; for(...) c[i] = foo; 工作
      • 不,你没看错。大多数 OO 语言(我用过的)都以相同的方式创建对象数组。
      • 这需要 var 是一个指针数组。 B ** var;
      猜你喜欢
      • 2012-11-17
      • 2014-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 2012-04-20
      • 1970-01-01
      • 2021-11-08
      相关资源
      最近更新 更多