Essential C++学习记录&笔记整理38(运行时的鉴定机制)

这一节说了点新东西。

目录

  • 运行时类型鉴定机制(RTTI)
    • typeid运算符
    • type_info类
      • static_cast运算符
      • dynamic_cast运算符

运行时类型鉴定机制(RTTI)

typeid运算符

  • 这是运行时类型鉴定机制得一部分,由程序语言支持。
  • typeid运算符让我们得以查询多态化的类指针/引用,来获得类指针/引用所指对象的实际类型。用法举例:
#include
inline const char* num_sequence::what_am_i()const{return typeid(*this).name();}
  • 用法说明:
    欲用typeid运算符(typeid()),必须包含其头文件typeinfo- ->#include
    typeid运算符返回一个type_info对象,该对象存储和类型相关的种种信息。
    每个多态类,都对应一个type_info对象,,举个例子,比如我前几篇笔记提到的Fibonacci、Pell、Triangular、Square等派生类,这每一个派生类都对应着一个type_info对象,该对象的name()函数会返回一个const char*用于表示类名
  • 比如我上面提到的what_am_i()函数,这个函数中的typeid(*this)表达式,会返回一个type_info对象,关联到what_am_i()函数中this指针指向的类对象的实际类型

type_info类

  • type_info类支持相等和不相等两个操作,举个例子:
num_sequence *ps=&fib;
//...
if(typeid(*ps)==typeid(Fibonacci))
{}
//...

这一堆代码是测试ps这个基类指针是否指向某个派生类类对象。

  • 然而你如果想用基类指针调用派生类的成员函数,你不能写ps->gen_elements(64);也不能写ps->Fibonacci::gen_elems(64);
    为嘛?因为ps这是基类指针不是派生类指针。上面的检验操作只是 检验这个基类指针是不是指向派生类类对象,所以我必须把ps这个基类指针强制转换为派生类指针。
    怎么转换为派生类指针呢,这里一些运算符可以帮你做到。

static_cast运算符

用static_cast运算符来强制转换(无条件转换)基类指针变为派生类指针。用法举例:

if(typeid(*ps)==typeid(Fibonacci))
{
	Fibonacci *pf=static_cast<Fibonacci*>(*ps);
	pf->gen_elems(64);//经过static_cast运算符转换指针变为派生类指针
	//这种写法得以被编译器承认
}

不过static_cast有个潜在危险,就是编译器无法确定转换类指针从基类到派生类是不是转换对了,所以我们加了if(typeid(*ps)==typeid(Fibonacci)){}如果typeid运算符(这里是==和())运算结果为真,就执行类指针的无条件转换。

dynamic_cast运算符

dynamic_cast运算符没有这种潜在危险。其用法举例:

	if(Fibonacci *pf=dynamic_cast<Fibonacci*>(ps))
	{
		pf->gen_elems(64);//经过dynamic_Cast运算符转换指针变为派生类指针
		//这种写法得以被编译器承认
	}
	
  • 就行,dynamic_cast是一个RTTI运算符,在运行时进行检验操作,
  • 检验基类指针所指类对象是不是某派生类的类对象,
  • 如果是,进行类指针转换,于是这个例子中pf派生类类指针指向了派生类类对象。
  • 如果基类指针所指类对象是不是某派生类的类对象,则dynamic_cast运算符返回0,上面这个例子中就相当于了if(0),对派生类的成员函数进行的静态调用操作也就不会发生

你可能感兴趣的:(C++,c++)