C ++多态性中的访问冲突(指向错误位置的虚拟指针函数?)

Access violation in C++ polymorphism (virtual pointer function pointing to wrong place?)

这越来越奇怪了。 Ship 继承自Entity,MerchantShip 继承自Ship,其他类型待补,但基本思路,教授问的是,我使用多态,这样我就可以在main class(分配内存的指针在我的实现中用作数组),因此在后面的所有三个 classes 中都有一个 virtual void 更新。事实上,我已经使用了所有可能有意义的虚函数和非虚函数的组合。代码:

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

using namespace std;


class Entity
{
public:
    int x, y;
    virtual void update() = 0;
    void print()
    {
        cout << "x:" << x << ", y:" << y << endl;
    }
};

class Ship: public Entity
{
public:
    virtual void update()
    {
        Move();
    }

    void Move(){x++;};
};

class MerchantShip: public Ship
{
public:
    void update()
    {
        DontMove();
    }

    void DontMove(){};
};

int main(int argc, char* argv[])
{
    int EntityNumber = 2;
    Entity* entities;
    entities = (Entity*)malloc(EntityNumber*sizeof(Entity));
    for (int i = 0; i < EntityNumber; i++)
    {
        entities[i].print();
        entities[i].update();
        entities[i].print();
        cout << endl << "next ship: " << endl;
    }
    system("PAUSE");
    return 0;
}

好的,所以它编译得很好(stdafx.h 仅在 Visual Studio 中需要)但是我收到一个运行时错误,这是在它试图进入被覆盖的更新函数时在 0xffffffffffffffff 处的访问冲突。在调试信息中,它始终看起来像虚函数指针 (__vfptr) 明显指向其他地方而不是它应该在的地方 (0xcdcdcdcdcdcdcdcd),而且它总是相同的位置,即使在另一个代码中我试图做同样的事情.

目前研究: 原因 #1(不适用):在调用前释放的 DLL 中使用函数 原因#2(再次不适用):程序员忘记继承。 我没有在任何具有相同问题的线程中遇到任何其他问题,并且我已经调试了几天。如果我删除覆盖,它只会调用 Base class 的函数。 有什么线索吗?

您不应使用 malloc 分配 C++ 对象。 new 是正确的运算符。

您将无法实例化 Entity,因为它是一个抽象 class。

你需要的是指向 Entity 的指针数组,并将它们关联到具体 EntityShipMerchantShip)的地址,如下所示:

typedef Entity *PEntity;
PEntity entities[2];
entities[0] = new Ship();
entities[1] = new MerchantShip();

当您通过指针调用虚方法时,多态性将正确应用:

for (int i=0; i<2; i++) {
  entities[i]->print();
  entities[i]->update();
  entities[i]->print();
}

真正重要的是要明白这里没有Entity,只有具体的EntityEntity只是一个概念; Ship(或MerchantShip)是其具体实现之一。您可以通过它们的抽象接口来操作具体对象。

malloc 不创建和初始化对象,只是保留一块内存。在 C++ 中,您应该远离手动分配的动态数组并使用 std::vector 而不是

#include "stdafx.h"
// these headers are discouraged. Use cstdlib and cstdio instead.
//#include <stdlib.h> 
//#include <stdio.h>

#include <iostream>
#include <vector>
#include <memory>

using namespace std;


class Entity
{
public:
    int x, y;
    virtual void update() = 0;
    void print()
    {
        cout << "x:" << x << ", y:" << y << endl;
    }

    virtual ~Entity() {} // any base-class should have this
};

class Ship: public Entity
{
public:
    virtual void update()
    {
        Move();
    }

    void Move(){x++;};
};

class MerchantShip: public Ship
{
public:
    void update()
    {
        DontMove();
    }

    void DontMove(){};
};

int main(int argc, char* argv[])
{
    int EntityNumber = 2;
    std::vector<std::unique_ptr<Entity>> entities(EntityNumber);

    // the array is empty so you have to create some objects in it
    entities[0] = new MerchantShip;
    entities[1] = new Ship;

    for (int i = 0; i < EntityNumber; i++)
    {
        entities[i].print();
        entities[i].update();
        entities[i].print();
        cout << endl << "next ship: " << endl;
    }

    system("PAUSE");
    return 0;
}

我还在你的基础上添加了一个虚拟析构函数class。