栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > C/C++/C#

【运行时的类型识别】

C/C++/C# 更新时间:发布时间: 百科书网 趣学号

RTTI (运行时类型识别 ) :允许"用指向基类的指针或引用来操纵对象" 的程序能够获取到," 这些指
针或引用所指对象" 的实际派生类型。
在C++中为了支持 RTTI 提供了两个操作符:

  1. typeid 操作符,它在程序中可用于获取一个表达式的类型 ;
    查询类型的信息, 类型身份认证。它指出指针或引用指向对象的实际派生类型。
  2. dynamic_cast 操作符可以用来把一个类类型对象的指针,转换成同一类层次结构中的其他类的指针 ,同时也可以用它把一个类类型对象的左值,转换成同一类层次结构中其他类的引用。
    dynamic_cast 和 typeid 操作符的操作数的类型 ,必须是带有一个或多个虚拟函数的类类型。 即对于带有虚拟函数的类而言 RTTI 操作符是运行时刻的事件 ,而对于其他类而言,它只是编译时刻的事件。

重点:
在所有情况下, typeid 都忽略顶层的 cv 限定符 !!!!!。

1. typeid 操作符(运行时的类型识别)

1.typeid() 指出指针或引用指向对象的实际派生类型。

class Object
{
	int val;
public:
	Object(int x=0) :val(x){}
	~Object() {}
	 virtual void fun(){}
};
int main()
{
	Object* op = nullptr;
	Object obja;
	cout << typeid(op).name() << endl; //class Object *
	cout << typeid(obja).name() << endl;//Object
	cout << typeid(*op).name() << endl;//error //op没有指向到派生类对象
	return 0; 
}

cout<

我们把fun()函数的virtual 关键字去掉看看会发生什么:

class Object
{
	 void fun(){}
};
int main()
{
	Object* op = nullptr;
	Object obja;
	cout << typeid(*op).name() << endl;//ok //class object
	return 0; 
}


为什么去掉了virtual关键字打印的是object类型?
我们猜测,去掉了关键字的typeid()是在编译时类型识别,而不是在运行时。
2.忽略CV限定符
当typeid()识别指针和引用时,const 不忽略,可以显示出来;当typeid()指向对象时,将忽略CV限定符(不显示)。

class Object
{
public:
	Object(int x=0) :val(x)
	{}
	~Object() {}
	  virtual void fun(){}
};
class Base :public Object 
{
public:
	virtual void fun() {}
};
int main()
{
	const Base base1;
	const Object* ip = nullptr;
	const Object* op = &base1;
	 Object obja;
	cout << typeid(*op).name() << endl; //class
	cout << typeid(obja).name() << endl;
	cout << typeid(ip).name() << endl;
	return 0;
}


一个带有函数模板的小例子:

class Object
{
	int val;
public:
	Object(int x=0) :val(x)
	{}
	~Object() {}
	  virtual void fun()
	{
	}

};
class Base :public Object 
{
public:
	virtual void fun() {}
};
template
void func(T& x)
{
	cout << typeid(x).name();//class object
	T y;
	cout << typeid(y).name();
}
int main()
{
	Object obja(10);
	Object objb(20);
	func(obja);
	return 0;
}

以下程序的问题?

template
void func(T& x)
{

	cout << typeid(x).name();
	T y;//error  const 常性类型必须要初始化
	cout << typeid(y).name();
}
int main()
{
	const int a = 10;
	func(a);
	return 0;
}

4 . dynamic_cast

语法:dynamic_cast < typen_ame> ( expression )
说明:dynamic_cast 操作符, 它允许在运行时刻进行类型转换 ,从而使程序能够在一个类层次结构中安全地转换类型, 把基类指针转换成派生类指针,或把指向基类的左值转换成派生类的引用。
必须是公有继承,基类要有虚函数。
特点:

  1. 与C++支持的其他强制转换不同的是, dynamic_cast 是在运行时执行的类型转换。
  2. 如果针对指针类型的 dynamic_cast 失败, 则dynamic_cast 的结果是 nullptr。
  3. 如果针对引用类型的 dynamic_cast 失败, 则 dynamic_cast 会抛出一个异常。
  4. 在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。
  5. 在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
1.下行转换(主要)

会出现一个什么潜在的危险?几个错误和一个正确的例子(把person*p= 那行代码指向改改再试试)


那么动态转换的原理是什么?

在这里插入代码片
2.上行转换


都是静态转换
不用转换关键字也可以。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/1034032.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号