这变得很奇怪。 Ship继承自Ship的Entity和MerchantShip,其他类型将在以后添加,但基本思想和教授要求的是我使用多态,以便我可以处理主类的集合(指针在我的实现中使用已分配的内存作为数组),因此在后面的所有三个类中都有一个虚拟的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)指向其应该位置的其他位置(0xcdcdcdcdcdcdcdcdcd),它始终是相同的位置,即使在我试图做同样事情的另一个代码中。
到目前为止的研究: 原因#1(不适用):在被调用之前释放的DLL中使用函数 原因#2(再次不适用):程序员忘记继承。 我没有在任何具有相同问题的线程中遇到任何其他问题,并且我已经调试了几天。如果我删除覆盖它将只调用Base类的函数。 有线索吗?
答案 0 :(得分:4)
您不应该使用malloc
来分配C ++对象。 new
是正确的运算符。
您将无法实例化Entity
,因为它是一个抽象类。
您需要的是一系列指向Entity
的指针,并将其与具体Entity
(Ship
或MerchantShip
)的地址相关联,如下所示:
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
,只是具体Entity
。 Entity
只是一个概念; Ship
(或MerchantShip
)是其具体实现之一。您可以通过抽象接口操作具体对象。
答案 1 :(得分:1)
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;
}
我还在你的基类中添加了一个虚析构函数。