概述
参考于 https://blog.csdn.net/gatieme/article/details/50947821
typeid关键字
注意:typeid是操作符,不是函数。这点与sizeof类似)
RTTI(Run-TimeType Identification, 运行时类型识别),它提供了运行时确定对象类型的方法。它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许“用指向基类的指针或引用来操作对象”的程序能够获取到“这些指针或引用所指对象”的实际派生类型。
在C++中,为了支持RTTI提供了两个操作符:dynamic_cast和typeid
- dynamic_cast允许运行时刻进行类型转换,从而使程序能够在一个类层次结构中安全地转化类型
- typeid是C++的一个关键字,等同于sizeof这类操作符。typeid操作符的返回结果是名为type_info的标准库类型的对象的引用。type_info的name成员函数返回C-style的字符串。
实现机制与使用技巧
- 如果表达式的类型是类类型且至少包含有一个虚函数(由于此时的基类不具有多态性),则typeid操作符返回表达式的动态类型,需要在运行时计算,否则,typeid操作符返回表达式的静态类型,在编译时就可以计算。
- type_info类提供了public虚 析构函数,以使用户能够用其作为基类。它的默认构造函数和拷贝构造函数及赋值操作符都定义为private,所以不能定义或复制type_info类型的对象。程序中创建type_info对象的唯一方法是使用typeid操作符(由此可见,如果把typeid看作函数的话,其应该是type_info的 友元)。type_info的name成员函数返回C-style的字符串,用来表示相应的类型名,但务必注意这个返回的类型名与程序中使用的相应类型名并不一定一致(往往如此,见后面的程序),这具体由编译器的实现所决定的,标准只要求实现为每个类型返回唯一的字符串。
使用typeid时应注意:
(1)、typeid运算符允许在运行时确定对象的类型;
(2)、typeid的结果是const type_info&;
(3)、typeid运算符在应用于多态类类型的左值时执行运行时检查,其中对象的实际类型不能由提供的静态信息确定;
(4)、typeid也可在模板中使用以确定模板参数的类型;
(5)、typeid是操作符,不是函数,运行时获知变量类型名称;
(6)、要使用typeid,首先要确保编译器开启了运行时类型检查(RTTI)。
type_info类源代码
#ifndef _TYPEINFO
#define _TYPEINFO
#include <exception>
namespace std
{
class type_info
{
public:
virtual ~type_info();
{ return __name[0] == '*' ? __name + 1 : __name; }
bool before(const type_info& __arg) const
{ return __name < __arg.__name; }
bool operator==(const type_info& __arg) const
{ return __name == __arg.__name; }
bool operator!=(const type_info& __arg) const
{ return !operator==(__arg); }
virtual bool __is_pointer_p() const;
virtual bool __is_function_p() const;
protected:
const char *__name;
explicit type_info(const char *__n): __name(__n) { }
private:
type_info& operator=(const type_info&);
type_info(const type_info&);
};
} // extern "C++"
#endif
程序代码实例
#include <iostream>
using namespace std;
class Base
{
public:
virtual void fun(){ cout << "this is Base fun calln"; }; //此处有虚函数
};
class Derived:public Base
{
//
};
class father
{
public:
void fun()
{
cout << "this is father fun calln"; //此处没有虚函数
}
};
class son : public father
{
//
};
int main()
{
Derived derived;
Base *p = new Base;
p = &derived;
son son1;
father * fp = new father;
fp = &son1;
cout << "有虚函数:" << typeid(p).name() << "t" << "没有虚函数:" << typeid(fp).name() << "t" << "两种都是打印的是基类的指针类型" << endl;
cout << "有虚函数:" << typeid(*p).name() << "t" << "没有虚函数:" << typeid(*fp).name() << "t" << "有虚函数打印的会根据运行时p所指向的实际类型去计算" << endl;
cout << "有虚函数:" << typeid(Base).name() << "t" << "没有虚函数:" << typeid(father).name() << "t" << "both same" << endl;
cout << "有虚函数:" << typeid(Derived).name() << "t" << "没有虚函数:" << typeid(son).name() << "t" << "both same" << endl;
cout << "有虚函数:" << typeid(Base*).name() << "t" << "没有虚函数:" << typeid(father*).name() << "t" << "both same" << endl;
cout << "有虚函数:" << typeid(Derived*).name() << "t" << "没有虚函数:" << typeid(son*).name() << "t" << "both same" << endl;
system("pause");
return 0;
}
有虚函数:class Base * 没有虚函数:class father * 两种都是打印的是基类的指针类型
有虚函数:class Derived 没有虚函数:class father 有虚函数打印的会根据运行时p所指向的实际类型去计算
有虚函数:class Base 没有虚函数:class father both same
有虚函数:class Derived 没有虚函数:class son both same
有虚函数:class Base * 没有虚函数:class father * both same
有虚函数:class Derived * 没有虚函数:class son * both same
请按任意键继续. . .
代码解释
- 定义了一种Base基类带虚函数,继承于它的子类Derived。此实现方式具有多态性,在执行typeid().name()函数时,会动态的计算。如typeid§.name(),打印的是class Base *,当执行typeid(*p).name()时,打印的是classDerived,因为此时基类具有多态性,打印的是p真正所指向的对象,而本例中p指向的是派生类对象,现在p真正指向的是其子类Derived,所以打印的是class Derived。*因此表达式typeid(p) == typeid(derived)为真。
- 第二种是不带虚函数的基类father,所以执行的结果本质是没有区别的。
最后
以上就是有魅力流沙为你收集整理的获取基类指针指向什么派生类(typeid)的全部内容,希望文章能够帮你解决获取基类指针指向什么派生类(typeid)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复