rtti
2018-06-18 00:02:39来源:未知 阅读 ()
RTTI(Run-Time Type Identification),通过运行时类型信息程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。
C++ 里通过虚函数增加额外信息的方法实现了RTTI。GCC和VS的实现也大同小异,并且都有专门的设置来开关来禁止或使用RTTI。
和RTTI相关操作的函数是typeid和dynamic_cast.
这里将结合前面的内容,自己实现一个RTTI。
1.定义
1 namespace blog { 2 class Object; 3 class Type 4 { 5 public: 6 struct Rtti 7 { 8 public: 9 typedef const Rtti& (*TypeId)(void); 10 public: 11 Rtti( 12 const Type* baseType, 13 const char *pname, 14 long long hash, 15 Object* (*constructor)() = nullptr 16 ); 17 Object* newObject()const; 18 const Type* Id()const; 19 const char* getName()const; 20 long long getHash()const; 21 const Type* getBaseTypes()const { return _baseType; } 22 23 bool isExactKindOf(const Type& type) const; 24 bool isKindOf(const Type& baseRtti) const; 25 26 private: 27 const Type* _baseType; 28 const char* _name; 29 long long _hash; 30 Object* (*_constructor)(); 31 }; 32 public: 33 Type(); 34 Type(const Rtti::TypeId type); 35 bool operator == (Type type)const; 36 bool operator != (Type type)const; 37 const char* getName()const; 38 long long getHash()const; 39 Object* newObject()const; 40 41 bool isKindOf(Type id)const; 42 bool isExactKindOf(Type id)const; 43 const Type* getBaseTypes()const; 44 45 typedef Rtti::TypeId ID; 46 const static Type vNone; 47 private: 48 Rtti::TypeId _typeid; 49 }; 50 }
其中Object是将实现RTTI的类,Type是封装类的TypeId,其中的struct Rtti将保存类的基本信息
下面定义Object基础类以及其派生类
1 class Object : public Memory 2 { 3 private: 4 static Object* New() { return new Object(); } 5 friend class Type; 6 public: 7 static const Type::Rtti& TypeId() 8 { 9 const static Type rtti[] = { nullptr }; 10 const static Type::Rtti inst(rtti, "Object", "Object"_hash, New); 11 return inst; 12 } 13 virtual Type getType()const { return TypeId; } 14 }; 15 class DerivedObject : public Object 16 { 17 private: 18 static Object* New() { return new DerivedObject(); } 19 public: 20 static const Type::Rtti& TypeId() 21 { 22 const static Type rtti[] = { Object::TypeId,nullptr }; 23 const static Type::Rtti inst(rtti, "DerivedObject", "DerivedObject"_hash, New); 24 return inst; 25 } 26 virtual Type getType()const override { return TypeId; } 27 };
2.使用
1 Type objType = Object::TypeId; 2 Object* obj = new Object(); 3 Type pobjType = obj->getType(); 4 std::cout << pobjType.getName() << std::endl; 5 delete obj; 6 obj = new DerivedObject(); 7 std::cout << obj->getType().getName() << std::endl; 8 std::cout << obj->getType().isKindOf(objType) << std::endl; 9 switch (obj->getType().getHash()) 10 { 11 case "Object"_hash: 12 std::cout << "Object" << std::endl; 13 break; 14 case "DerivedObject"_hash: 15 std::cout << "DerivedObject" << std::endl; 16 break; 17 default: 18 break; 19 } 20 delete obj;
3.结果
Object DerivedObject true DerivedObject
4.优缺点
该代码实现的是单继承的,且不能使用在模板类上。
可以通过宏定义的方式,简化代码书写。
1 class DerivedObject : public Object 2 { 3 DECL_RTTI(DerivedObject, Object); 4 };
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Run-Time Check Failure #0 - The value of ESP was not pro 2019-11-11
- 关于C 中RTTI的编码实现 2008-02-23
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash