运行时类型信息

基于几个底层的管理类Gamebryo设计成一个类的层次结构。下面的图展示了从NiObject派生的类的一个类层次结构的小子集。
以NiObject作为根节点的Gamebryo对象使用单继承的方式编写。这样NiObject的子类形成了一个类型树(注意这是类型之间的关系树不是指对象实例之间的关系)。运行时类型信息(RTTI)系统使得应用程序可以快速判断任何NiObject或其子类的直接类型或祖先类型
RTTI支持三个基本的操作:
    1.判断一个对象的是不是严格的指定类型
    2.判断一个对象是不是一个指定类型的派生类
    3.动态转换一个类对象的指针到派生类的指针

所有的NiObject 派生类必须使用NiDeclareRTTI宏来定义静态RTTI 数据成员。  用来在运行时刻检测类类型。要实现动态类型识别非常简单,只需类似如下操作
因为c++开启运行时刻类型识别是非常浪费效率的行为,不是一个商业程序应该做的。而很多库都提供了自己的类型识别。Gamebryo 也提供了这样一个快速的
类型检测类型。几乎所有的类都是从其派生的
// NiNewClass.h
class NiNewClass : public NiAVObject 
{
    NiDeclareRTTI;
    // <other stuff>
};

// NiNewClass.cpp
NiImplementRTTI(NiNewClass, NiAVObject);

常用函数:
  NiIsKindOf           判断类对象是否是一个类型或者该类型的父类型
  NiIsExactKindOf      判断一个类对象是否为某种类型。但不包含其父类型 
  NiDynamicCast        动态转换一个类为其原类型或者父类型
示例:
NiNode* pkNode = NiNew NiNode;
bool bResult;
bResult = NiIsExactKindOf(NiNode, pkNode);     // bResult is true
bResult = NiIsExactKindOf(NiAVObject, pkNode); // bResult is false
bResult = NiIsKindOf(NiAVObject, pkNode);      // bResult is true
bResult = NiIsKindOf(NiSwitchNode, pkNode);    // bResult is false
 
NiObject* pkObject = pkNode;
NiAVObject* pkDynAVObj = NiDynamicCast(NiAVObject, pkObject);   // pkDynAVObj == pkNode
NiNode* pkDynNode = NiDynamicCast(NiNode, pkObject);            // pkDynNode == pkNode
NiSwitchNode* pkDynSw = NiDynamicCast(NiSwitchNode, pkObject);  // pkDynSw == 0

 应该避免类似下面的代码:
void Function(NiAVObject* pkObject)
{
    if (NiIsKindOf(NiNode, pkObject))
    {
        NiNode* pkNode = NiDynamicCast(NiNode, pkObject);
        // do something with pkNode
    }
}

NiDynamicCast 判断转换是否安全实质上重复了NiIsKindOf的工作。在NiIsKingOf已经判断对象是确定的类型时,静态转换到这个类型就是安全的。上面函数更好的写法如下:
void Function(NiAVObject* pkObject)
{
    if (NiIsKindOf(NiNode, pkObject))
    {
        NiNode* pkNode = (NiNode*) pkObject;
        // do something with pkNode
    }
}
The following code shows how NiObject is set up and how derived classes are set up.

// NiObject.h

class NiObject : public NiRefObject
{
    NiDeclareRootRTTI(NiObject);
    // <other NiObject stuff goes here>
};

 

// NiObject.cpp

NiImplementRootRTTI(NiObject);

 

// NiObjectNET.h

class NiObjectNET : public NiObject
{
    NiDeclareRTTI;
    // <other NiObjectNET stuff goes here>
};

 

// NiObjectNET.cpp

NiImplementRTTI(NiObjectNET, NiObject);

 

// NiAVObject.h

class NiAVObject : public NiObjectNET 
{
    NiDeclareRTTI;
    // <other stuff>
};
 
// NiAVObject.cpp
NiImplementRTTI(NiAVObject, NiObjectNET);

你可能感兴趣的:(类型)