🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 15.5 提供运行期类型信息 提供运行期类型信息 和大多数编程框架一样,wxWidgets提供了比标准C++更多的运行期类型信息.这对于在运行期依对象类型决定行为,或者在上节提到的错误报告中都是很有用处的.并且它还允许你通过对象名来创建一个那种类型的变量.需要注意的是:只有派生自wxObject的类才可以使用wxWidgets的RTTI (运行期类型信息). 如果你不需要动态创建功能,你需要在类声明中使用DECLARE_CLASS(class)宏,而在类实现中使用 IMPLEMENT_CLASS(class, baseClass)宏,反之,则需要使用DECLARE_DYNAMIC_CLASS(class)宏和IMPLEMENT_DYNAMIC_ CLASS(class, baseClass)宏.另外,如果你希望使用动态创建功能,你还需要保证你的类拥有一个默认的构造函数,否则在编译那些用来动态产生某个对象的代码时, 编译器可能会报错. 下面是定义和动态创建一个对象的例子: ``` class MyRecord: public wxObject { DECLARE_DYNAMIC_CLASS(MyRecord) public: MyRecord() {} MyRecord(const wxString& name) { m_name = name; } void SetName(const wxString& name) { m_name = name; } const wxString& GetName() const { return m_name; } private: wxString m_name; }; IMPLEMENT_DYNAMIC_CLASS(MyRecord, wxObject) MyRecord* CreateMyRecord(const wxString& name) { MyRecord* rec = wxDynamicCast(wxCreateDynamicObject(wxT("MyRecord")), MyRecord); if (rec) rec->SetName(name); return rec; } ``` 当CreateMyRecord被调用的时候,wxCreateDynamicObject负责创建所需的对象,而 wxDynamicCast则负责进行类型检查,如果检查失败则返回NULL.也许你觉得这个代码看上去并没有什么实际的用处,但是在从文件加载一堆不同类型的对象的时候,这是非常有用的.对象的数据和它的名称被一起存放在文件中,通过名字创建一个对象的实例,然后再使用这个实例加载相应的数据. 下面我们来介绍以下运行期类型信息的一起其它相关宏: CLASSINFO(class)返回一个指向wxClassInfo类型的指针.你可以使用wxObject::IsKindOf函数来判断某个对象是否是对应的类型: ``` if (obj->IsKindOf(CLASSINFO(MyRecord))) { ... } ``` 使用DECLARE_ABSTRACT_CLASS(class)和IMPLEMENT_ABSTRACT_CLASS(class, baseClass)来定义虚类. 使用DECLARE_CLASS2(class)和IMPLEMENT_CLASS2(class, baseClass1, baseClass2)来定义有两个父类的类. 使用DECLARE_APP(class)和IMPLEMENT_APP(class)来使得wxWidgets知道整个应用程序类的运行期类型信息. wxConstCast(ptr, class)用来代替const_cast<class *>(ptr),如果编译器不支持const_cast,则使用旧的C语言的类型强制转换. wxDynamicCastThis(class)相当于wxDynamicCast(this, class), 但是后者在某些编译器上会导致永真比较告警,因为它将测试是否指针为空,而this指针永远不可能为空,前者可以避免这个告警. wxStaticCast(ptr, class)在调试模式将检查强制类型转换的有效性(如果wxDynamicCast(ptr, class) == NULL将引发断言错误)然后返回static_cast<class*>(ptr)的等同结果. wx_const_cast(T, x)在编译器支持的情况下等同于const_cast<T>(x),否则等同于(T)x(C语言类型强制转换语法).和 wxConstCast不同的是,它强制转换的是T本身而不是指向T的指针,而且参数的顺序也和标准强制转换的顺序相同. wx_reinterpret_cast(T, x)则相当于reinterpret_cast<T>(x),如果编译器不支持则等同于(T)x. wx_static_cast(T, x)等同于static_cast<T>(x),如果编译器不支持则等同于(T)x. 和wxStaticCast不同的是,它不做类型检查,并且采用和标准的静态转换相同的参数顺序,而且转换的也是T而不是指向T的指针.