RTTI

MyGUI 运行时类是通过一系列宏做到的

例如获得运行时类名:template+宏

		#define MYGUI_DECLARE_TYPE_NAME( Type ) \
		public: \
			static const std::string& getClassTypeName() { static std::string type = #Type; return type; } \
			/** Get type name as string */ \
			virtual const std::string& getTypeName() const { return Type::getClassTypeName(); }

typeid


Base

	#define MYGUI_RTTI_BASE( BaseType ) \
		public: \
			typedef BaseType RTTIBase; \
			MYGUI_DECLARE_TYPE_NAME( BaseType ) \
			/** Compare with selected type */ \
			virtual bool isType( const std::type_info& _type) const { return typeid( BaseType ) == _type; } \
			/** Compare with selected type */ \
			template<typename Type> bool isType() const { return isType( typeid( Type )); } \
			/** Try to cast pointer to selected type. \
				@param _throw If true throw exception when casting in wrong type, else return nullptr \
			*/ \
			template<typename Type> Type* castType(bool _throw = true) \
			{ \
				if (this->isType<Type>()) return static_cast<Type*>( this ); \
				MYGUI_ASSERT(!_throw, "Error cast type '" << this->getTypeName() << "' to type '" << Type::getClassTypeName() << "' .") \
				return nullptr; \
			} \
			/** Try to cast pointer to selected type. \
				@param _throw If true throw exception when casting in wrong type, else return nullptr \
			*/ \
			template<typename Type> const Type* castType(bool _throw = true) const \
			{ \
				if (this->isType<Type>()) return static_cast<Type*>( this ); \
				MYGUI_ASSERT(!_throw, "Error cast type '" << this->getTypeName() << "' to type '" << Type::getClassTypeName() << "' .") \
				return nullptr; \
			}

例如 Widget 和 Object 都包含 上类runtime 定义

	#define MYGUI_RTTI_DERIVED( DerivedType ) \
		public: \
			MYGUI_DECLARE_TYPE_NAME( DerivedType ) \
			typedef RTTIBase Base; \
			typedef DerivedType RTTIBase; \
			/** Compare with selected type */ \
			virtual bool isType( const std::type_info& _type ) const { return typeid( DerivedType ) == _type || Base::isType( _type ); } \
			/** Compare with selected type */ \
			template<typename Type> bool isType() const { return isType( typeid( DerivedType )); }

定义staticEidt 和 Button



### RTTI 技术原理 RTTI(Runtime Type Identification,运行时类型识别)是一种编程语言特性,允许程序在运行期间动态地获取对象的类型信息。这种技术的核心在于编译器为每个类生成额外的元数据,这些元数据包含了类名、继承关系、成员变量和方法等信息,并且通常会在程序启动时或首次使用某个类时加载到内存中。当程序尝试访问一个对象的类型信息时,RTTI 会通过检查对象的虚函数表指针来定位对应的类型描述符[^1]。 ### 使用场景 - **调试与日志记录**:在开发过程中,开发者经常需要打印出对象的实际类型以帮助理解程序的行为或是进行问题诊断。 - **序列化/反序列化**:当需要将对象的状态保存下来或者在网络上传输时,可以通过 RTTI 获取对象的结构信息,从而正确地将其转换为字节流或将字节流还原成对象。 - **插件系统**:软件架构中可能会有插件机制,其中主应用程序加载并使用未知类型的组件。在这种情况下,RTTI 可用于验证插件提供的接口是否符合预期。 - **反射库**:某些高级功能如反射库依赖于 RTTI 来实现对任意对象的方法调用和属性访问,这在脚本绑定或自动化测试工具中非常有用[^1]。 ### 问题排查 在使用 RTTI 时遇到的问题可能包括但不限于以下几点: - **性能开销**:由于 RTTI 需要在运行时维护类型信息,它可能导致轻微的性能下降。如果发现应用有明显的延迟,可以考虑禁用不需要的地方的 RTTI 功能。 - **二进制兼容性**:不同版本之间的编译器更新可能会导致生成的类型信息发生变化,进而影响到已经存在的二进制文件。确保所有相关的代码都是用相同版本的编译器构建可以帮助避免这类问题。 - **安全性和隐私**:暴露过多的类型信息可能会给恶意用户提供了攻击线索。对于安全性要求较高的项目,应该仔细审查哪些类型信息是必要的,并限制不必要的暴露。 - **跨平台支持**:虽然标准 C++ 支持 RTTI,但不同的操作系统和硬件平台上其表现可能有所差异。编写可移植的应用程序时,应考虑到这一点,并做好充分的测试工作。 针对上述情况,一旦确定了具体的问题所在,接下来就可以采取相应的措施来解决这些问题,例如优化代码逻辑减少 RTTI 的使用频率,调整编译选项以控制 RTTI 的开启关闭状态,或者是采用其他替代方案如自定义类型标识符等方法来绕过 RTTI 带来的限制。 ```cpp #include <typeinfo> #include <iostream> class Base { public: virtual ~Base() {} // 必须至少有一个虚函数才能启用RTTI }; class Derived : public Base {}; int main() { Base base; Derived derived; std::cout << "Type of base: " << typeid(base).name() << '\n'; std::cout << "Type of derived: " << typeid(derived).name() << '\n'; Base* ptr = &derived; std::cout << "Type pointed to by ptr: " << typeid(*ptr).name() << '\n'; // 输出Derived的类型名称 return 0; } ``` 这段示例代码演示了如何利用 `typeid` 运算符以及 `<typeinfo>` 头文件中的 `std::type_info` 类来获取对象的具体类型信息。注意这里为了启用 RTTI 特性,基类 `Base` 中声明了一个虚析构函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值