- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在尝试将一个类向下转换为另一个类以访问该类的特定方法时遇到了几个问题。这是我目前的类(class)计划:
游戏对象类:
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_;
}
小妖精类:
#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 Enemy\n";
}
}
...
}
(敌人是对 GameObject 对象的引用,但我知道它实际上是一个 SmallGoblin 对象)。
在我的代码的其他部分,我有另一个类 (Door),它扩展了 GameObject 类并且向下转换有效(但是,我必须使用 static_cast 而不是 dynamic_cast 我不知道为什么)。
最佳答案
您在您的评论之一中提到您正在存储 std::vector<GameObject>
.不幸的是,这会导致您的 GameObject
对象 sliced .可以在此处找到很好的描述:What is object slicing?
"Slicing" is where you assign an object of a derived class to an instance of a base class, thereby losing part of the information - some of it is "sliced" away.
要解决这个问题,您需要存储一个指针 vector 。如果您使用的是 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
将取决于您需要如何使用这些对象。
关于c++ - 向下转换 dynamic_cast 和多态类不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16268014/
我来自 Asp.Net 世界,试图理解 Angular State 的含义。 什么是 Angular 状态?它类似于Asp.Net中的ascx组件吗?是子页面吗?它类似于工作流程状态吗? 我听到很多人
我一直在寻找 3 态拨动开关,但运气不佳。 基本上我需要一个具有以下状态的开关: |开 |不适用 |关 | slider 默认从中间开始,一旦用户向左或向右滑动,就无法回到N/A(未回答)状态。 有人
我是一名优秀的程序员,十分优秀!