将指针从基类型转换为子类型

The*_*777 7 c++ polymorphism

我正在为我的一个项目构建一个简单的游戏设计.我有以下课程:

class Character
{
public: 
   virtual void Display();
   virtual void SetParameters( char* param, ... );
};

class NonPlayableCharacter : public Character
{

public:
   virtual void Display();
   virtual void SetParameters( char* paaram, ... );
   int GetNPCState();
}
Run Code Online (Sandbox Code Playgroud)

然后我有一堆派生自Character或NonPlayableCharacter的类.我这样定义它:

std::vector<Character*> _allChar;
Run Code Online (Sandbox Code Playgroud)

我的问题是,在任何给定的时间我都想对矢量的一个元素执行一些操作.因此,从向量中获取元素我无法直接调用该方法,GetNPCState()因为向量中的元素是Character*类型.这样做:

_allChar[0]->GetNPCState();
Run Code Online (Sandbox Code Playgroud)

不起作用.所以我尝试用着名的dynamic_cast来做:

NonPlayableCharacter* test = dynamic_cast<NonPlayableCharacter*>(_allChar[0]);
test->GetNPCState();
Run Code Online (Sandbox Code Playgroud)

最后一次尝试的问题是GetNPCState()崩溃,因为对象是null,我知道(通过调试)_allChar [0]不为空.

Mat*_* M. 6

C++(4)中有几种类型的强制转换,其中2个是有兴趣的:

  • static_cast 假设你知道自己在做什么
  • dynamic_cast 在运行时检查你"猜对"的权利

注意:简化,dynamic_cast也允许包含虚拟基础的交叉投射和强制转换.

dynamic_cast实际上有3个版本,具体取决于目标的性质:

  • 如果目标是引用(即dynamic_cast<T&>(u)),那么如果检查失败则dynamic_cast抛出std::bad_cast异常
  • 如果目标是指针(即dynamic_cast<T*>(p)),那么如果检查失败则dynamic_cast返回空指针
  • 最后,作为一种特殊情况,如果目标是void*,则dynamic_cast返回完整对象的地址

在这种情况下,您可以:

  • 切换dynamic_cast<NonPlayableCharacter*>(_allChar[0])->getNPCState()dynamic_cast<NonPlayableCharacter&>(*_allChar[0]).getNPCState(),并让异常传播
  • 测试cast(NonPlayableCharacter* test这里)的结果是否为非null


Luc*_*ore 5

NonPlayableCharacter* test = dynamic_cast<NonPlayableCharacter*>(_allChar[0]);
Run Code Online (Sandbox Code Playgroud)

你应该检查是否testNULL.即使_allChar[0]不是NULL,如果它指向的对象不是a ,dynamic_cast也可以返回.NULLNonPlayableCharacter

所以正确的版本是:

NonPlayableCharacter* test = dynamic_cast<NonPlayableCharacter*>(_allChar[0]);
if (test)
{
   test->GetNPCState();
}
Run Code Online (Sandbox Code Playgroud)