Downcasting与dynamic_cast和多态类不工作
Downcasting with dynamic_cast and polymorphic classes not working
我在试图将一个类向下转换为另一个类以访问该类的特定方法时遇到了几个问题。这是我目前的类方案:
GameObject类:
class GameObject
{
...
}
敌人类:
#include "../GameObject.h"
class Enemy : public GameObject
{
Enemy(Type type);
virtual ~Enemy();
virtual int receiveDamage(int attack_points);
virtual void levelUp() = 0;
...
protected:
char *name_;
int level_;
int health_;
int max_health_;
int attack_;
int armor_;
}
SmallGoblin类:
#include "../Enemy.h"
class SmallGoblin : public Enemy
{
public:
SmallGoblin();
~SmallGoblin();
void levelUp();
}
在我的代码中,我尝试这样做,每次都会抛出一个std::bad_cast异常。
class Player : GameObject
{
...
virtual void attack(GameObject &enemy)
{
try
{
Enemy &e = dynamic_cast<Enemy&>(enemy);
e.receiveDamage(attack_points_);
}
catch(const std::bad_cast& e)
{
std::cerr << e.what() << 'n';
std::cerr << "This object is not of type Enemyn";
}
}
...
}
(敌人是对GameObject对象的引用,但我知道它实际上是一个SmallGoblin对象)。
在我的代码的其他部分,我有另一个类(门)扩展GameObject类和向下投射工作(然而,我必须使用static_cast而不是dynamic_cast,我不知道为什么)。
您在其中一条评论中提到您正在存储std::vector<GameObject>
。不幸的是,这将导致您的GameObject
对象被切片。在这里可以找到一个很好的描述:什么是对象切片?
"切片"是指将派生类的对象分配给基类的实例,从而丢失部分信息——其中一些信息被"切片"了。
要解决这个问题,需要存储一个指针向量。如果使用c++ 11,这里有一些选择。您可以存储:
std::vector<GameObject*> badGameObjects;
std::vector<std::unique_ptr<GameObject>> uGameObjects;
std::vector<std::shared_ptr<GameObject>> sGameObjects;
所有这些选项将确保不会发生切片,因为vector只是存储指针。存储裸指针是最不可取的选择,因为您将不得不自己管理内存,并且可能成为内存泄漏的来源。unique_ptr
或shared_ptr
的使用将取决于您需要如何使用这些对象。
如果dynamic_cast
失败,那么enemy
实际上不是有效的Enemy
实例,因此请仔细检查您如何管理该引用。
当我尝试它时,以下工作对我来说很好:
class GameObject
{
public:
virtual ~GameObject(){}
};
enum Type {goblin};
class Enemy : public GameObject
{
public:
Enemy(Type type) : type_(type) {}
virtual ~Enemy() {}
virtual int receiveDamage(int attack_points) {}
virtual void levelUp() = 0;
protected:
Type type_;
//...
};
class SmallGoblin : public Enemy
{
public:
SmallGoblin() : Enemy(goblin) {}
~SmallGoblin() {}
void levelUp() {}
};
class Player : GameObject
{
public:
int attack_points_;
virtual void attack(GameObject &enemy)
{
try
{
Enemy &e = dynamic_cast<Enemy&>(enemy);
e.receiveDamage(attack_points_);
}
catch(const std::bad_cast& e)
{
std::cerr << e.what() << 'n';
std::cerr << "This object is not of type Enemyn";
}
}
};
.
Player p;
SmallGoblin goblin;
p.attack(goblin);
顺便说一句,我会用指针代替dynamic_cast
,以避免使用异常的不必要开销:
virtual void attack(GameObject &enemy)
{
Enemy *e = dynamic_cast<Enemy*>(&enemy);
if (e)
e->receiveDamage(attack_points_);
else
std::cerr << "This object is not of type Enemyn";
}
dynamic_cast
不应该用于向下转换,我很确定static_cast
可以完成这项工作。dynamic_cast
用于"上铸"
- 多态性和功能结合
- 具有默认模板参数的多态类的模板推导失败
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 多态二进制函数
- 访问存储在向量C++中的结构的多态成员
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 将 std::allocate_shared 与多态资源分配器一起使用
- 通过switch和static_cast访问多态对象的运行时类型
- C++ 多态性无法按预期工作
- 基于PHP示例,与C 中数据结构一起工作的多态性示例
- 从接口派生的模板 - 多态性停止工作
- 多态性在没有指针/引用的C++中工作吗
- 多态性不能正常工作
- C++中的多态性不能与引用一起正常工作
- 多态性和成员函数指针是如何工作的
- 弄清楚多态类型的c++指针是如何工作的
- 使多态性在C++映射中工作,而不会发生内存泄漏
- 向下转换到子类的问题,多态不能工作
- "delete"多态性是否正常工作?
- Downcasting与dynamic_cast和多态类不工作