我正在为简单的流氓式游戏制作一个简单的地图。 所以我需要通过从字符数组[i] [j]接收数据来初始化使用为每个数组单元创建的对象的映射。 建议这样的CWall,CDoor类在其他文件中定义,如CWall.cpp,CWall.h,Underneath是在map.cpp中初始化的代码
但这是正确的代码方式吗? 我认为这会导致分配内存的问题。
CObject CMap::insertObject(char character){
if (character = '*') {
CWall cwall;
return cwall;
}
if (character = 'D') {
CDoor cdoor;
return cdoor;
}
if (character = 'F') {
CFood cfood;
return cfood;
}
if (character = 'K') {
CKey ckey;
return ckey;
}
if (character = 'M') {
CMMonster cmmonster;
return cmmonster;
}
if (character = 'm') {
CMonster cmonster;
return cmonster;
}
if (character = '@') {
CPlayer cplayer;
return cplayer;
}
if (character = 'P') {
CPrincess cprincess;
return cprincess;
}
if (character = '&') {
CRock crock;
return crock;
}
if (character = 'S') {
CShield cshield
return cshield;
}
else {
CShield cshield;
return cshield;
}
}
void CMap::initialize(char arr[][COLS]){
for (int i = 0; i <= 11; i++){
for (int j = 0; j <= 38; j++){
char character = arr[i][j];
insertObject(character);
}
}
}
答案 0 :(得分:3)
这不是正确的做法。您受object slicing约束,因为我的猜测是您的CObject
是一个对象,而不是指向某个对象的指针。您需要在函数中返回类型为CObject*
的指针,然后针对每种情况返回new CMonster
或new CPlayer
等等。更好的是,使用智能指针代替。
您尝试实施的内容称为工厂方法模式,请参阅例如How to implement the factory method pattern in C++ correctly了解更多详情。
答案 1 :(得分:2)
虽然其他人正确地指出了如何编码您想要编码的想法,但我将专注于另一件事。即,这里多态性的使用不当。从无意义的对象继承一切就像Java一样,并且在C ++中不受欢迎。公主和怪物之间没有任何共同之处(一个是亲吻,另一个是被杀,并且做了最符合一个人品味的东西),所以当两者都是从Object继承时,它是非常难的编写适当的游戏机制。您还必须存储实际的对象类型(例如,枚举),而不是强制转换为此类型 - 因为只有其中一个将有方法kiss()
!
整个代码将是一个不安全演员的意大利面,无法维持或推理。
相反,选择强力打字的方式。始终知道你面前的类型!
答案 2 :(得分:1)
您应该动态处理数据。你现在正在做的有几个问题。
更好的方法是:
CObject* CMap::insertObject(char character){
if (character = '*') {
return new CWall();
}
...
这将利用多态来隐藏通用接口(CWall
)后面的实际类(例如CObject
)。在您编写它时,每个“新”对象(例如cdoor
)实际上将传递给CObject
的复制构造函数。其中没有一个实际上完成了任何有意义的事情。
当然,你需要将这些创作与正确的破坏配对。
答案 3 :(得分:0)
嗯,首先,你实际上并没有初始化任何东西。 CWall* cwall = new CWall;
将是动态分配和初始化新CWall对象的正确方法(假设CWall当然有一个默认构造函数),或任何对象。
您还需要记住的是,对于您使用new
分配的所有内容,您必须稍后取消分配delete
。因此,您需要考虑如何存储这些已分配的对象,这样您就可以确保析构函数或清理函数在完成后删除所有这些对象。要考虑的一种设计模式是Object Pool,尽管有很多好的方法可以做到这一点。不过,这是你必须自己做的步法,因为只有你对项目有足够的了解才能选择合适的设计模式。 (我链接的那本书是一个很好的资源。)
编辑:根据你的评论,还有另外一个问题,那就是你要返回不同类型的对象。这是继承的简单问题 - 只要所有这些对象都从CObject
(或类似的东西)的抽象基类继承,您只需将返回类型列为{{ 1}}。然后,只要你返回一个继承自CObject*
的对象(或指向一个对象的指针),你就是金色的。
编辑2:无论何时使用CObject
,您实际上都会获得指向动态分配对象的指针。这会产生一些问题,包括如果分配失败,new
可以返回空指针。一定要检查一下!智能指针可以防止许多这些问题,但您使用智能指针取决于您的设计模式选择。