您的位置:首页 > 编程语言 > C语言/C++

c++运行时类型识别(rtti)

2015-05-31 14:13 375 查看
一个简单运行时类型识别

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>();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: