一个简单运行时类型识别

namespace rtti_ex {

	/*
* 类型信息基类
*/
class i_type_info {
public:
// 判断是否是指定类型
bool is(const char* _name) const { return name() == _name; }
template<class T> bool is() const { return is(T::name()); } // 判断是否是派生类型
bool is_kind_of(const char* _name) const { return on_is_kind_of(_name); }
template<class T> bool is_kind_of() const { return is_kind_of(T::name()); } protected:
virtual bool on_is_kind_of(const char* name) const = 0;
virtual const std::string& name() const = 0;
}; /** 类型信息
* @_This 当前类
* @_Base 基类
* @_name_ 返回当前类名称的函数
*/
template<class _This, class _Base, const char*(*_name_)()>
class type_info : public _Base::type_info_t {
public:
type_info() : _name(_name_()) {} protected:
virtual bool on_is_kind_of(const char* name) const {
if (_name == name) {
return true;
}
return _Base::type_info_t::on_is_kind_of(name);
}
virtual const std::string& name() const { return _name; }; private:
const std::string _name;
}; /** 偏特化,最开始的基类类型(即没有继承的类)
*
*/
template<class _This, const char*(*_name_)()>
class type_info<_This, void, _name_> : public i_type_info{
public:
type_info() : _name(_name_()) {}
protected:
virtual bool on_is_kind_of(const char* name) const {
if (_name == name) {
return true;
}
return false;
}
virtual const std::string& name() const { return _name; };
private:
const std::string _name;
}; } #define REGIST_INFO_CLASS(ThisClass, BaseClass) \
public: \
static const char* name() { return #ThisClass; }\
typedef rtti_ex::type_info<ThisClass, BaseClass, name> type_info_t; \
virtual const rtti_ex::i_type_info& getinfo() { \
static type_info_t* s_info = nullptr; \
if (!s_info) { \
type_info_t* p = new type_info_t(); \
s_info = p; \
} \
return *s_info; \
}

测试:

class A {
REGIST_INFO_CLASS(A, void)
}; class B : public A {
REGIST_INFO_CLASS(B, A)
}; class C : public B{
REGIST_INFO_CLASS(C, B)
}; C c; A* a = &c;
bool b; b = a->getinfo().is<A>();
b = a->getinfo().is<B>();
b = a->getinfo().is<C>(); b = a->getinfo().is_kind_of<A>();
b = a->getinfo().is_kind_of<B>();
b = a->getinfo().is_kind_of<C>();

c++运行时类型识别(rtti)的更多相关文章

  1. C++学习之显式类型转换与运行时类型识别RTTI

    static_cast const_cast reinterpret_cast 运行时类型识别(RTTI) dynamic_cast 哪种情况下dynamic_cast和static_cast使用的情 ...

  2. C++之运行时类型识别RTTI

     C++ Code  12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...

  3. 运行时类型识别RTTI

    1.RTTI的工作原理 例1. 用Class加载对象示例. package RTTI; public class Candy { static{ System.out.println("Lo ...

  4. C++——运行时类型识别RTTI

    1.实现方式 typeid运算符,返回表达式的类型 dynamic_cast运算符,基类的指针或引用安全地转换成派生类的指针或引用 2.适用于:使用基类的指针或引用执行派生类的操作,且该操作不是虚函数 ...

  5. Java基础之RTTI 运行时类型识别

    运行时类型识别(RTTI, Run-Time Type Identification)是Java中非常有用的机制,在Java运行时,RTTI维护类的相关信息. 多态(polymorphism)是基于R ...

  6. RTTI 运行时类型识别 及异常处理

    RTTI   运行时类型识别 typeid  ------  dynamic_cast dynamic_cast 注意事项: 1.只能应用于指针和引用之间的转化 2.要转换的类型中必须包含虚函数 3. ...

  7. RTTI (Run-Time Type Identification,通过运行时类型识别) 转

    参考一: RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型.   RTTI提供了以下两个 ...

  8. MFC六大核心机制之二:运行时类型识别(RTTI)

    上一节讲的是MFC六大核心机制之一:MFC程序的初始化,本节继续讲解MFC六大核心机制之二:运行时类型识别(RTTI). typeid运算子 运行时类型识别(RTTI)即是程序执行过程中知道某个对象属 ...

  9. 框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解)

    框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解) 一丶什么是RTTI,以及RTTI怎么设计 通过第一讲,我们知道了怎么样升成一个窗口了,以及简单的消息循环. 第二讲则是主要讲解RTTI ...

随机推荐

  1. html中的a标签特例讲解

    将自己的博客写成了一个大杂烩了,遇见啥问题就写啥问题.但是当看见自己网页的成品就特别的开心. 还记得看见过的一个故事,说是收费的东西好还是免费的东西好,有一个答案是最让我记忆深刻的.回复的一个答案是: ...

  2. delphi edit 中undo 和clearundo 复制粘贴等总结

    edit 和memo都有undo功能, Undo:恢复到改动前. ClearUndo:撤销掉Undo缓冲区的内容,则将无法恢复到改动前的 从该文本框的撤销缓冲区中清除关于最近操作的信息,根据应用 程序 ...

  3. chapter9_3 协同程序实现迭代器

    将循环迭代器视为"生产者-消费者"模式的一种特例:迭代器产生的数据供循环体消费. 因此,用协同程序写迭代器就理所当然了.因为协同程序可以一改传统调用者与被调用者之间的关系. 有了这 ...

  4. Android 图片显示

    一.Android手机显示图片 若R.G.B每种颜色使用一个字节(8bit)表示,每幅图像可以有1670万种颜色:若R.G.B每种颜色使用两个字节(16bit)表示,每幅图像可以有10的12次方种颜色 ...

  5. android Bind机制(二)

    1.binder通信概述 binder通信是一种client-server的通信结构,    1.从表面上来看,是client通过获得一个server的代理接口,对server进行直接调用:    2 ...

  6. 转载 Deep learning:二(linear regression练习)

    前言 本文是多元线性回归的练习,这里练习的是最简单的二元线性回归,参考斯坦福大学的教学网http://openclassroom.stanford.edu/MainFolder/DocumentPag ...

  7. Flask -- 入门

    安装virtualenv 作用:可以为一个项目单独提供一份Python的安装,安全  pip install virtualenv 使用virtualenv为MyProject项目安装Python,并 ...

  8. HDU 5795 A Simple Nim

    打表找SG函数规律. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> ...

  9. point类型·

    指针的类型 不同类型的指针,从内存需求的观点来说,没有什么不同!他们三个都需要足够的内存来繁殖一个机器地址,"指向不同类型之各指针"之间的差异,既不在其指针表示法不同,也不再其内容 ...

  10. mysql 常用命令用法总结积木学院整理版

    一.启动与退出 1.进入MySQL:启动MySQL Command Line Client(MySQL的DOS界面),直接输入安装时的密码即可.此时的提示符是:mysql> 2.退出MySQL: ...