首页 > 编程语言 >C++使用typeid获取类型信息type_info机制解析

C++使用typeid获取类型信息type_info机制解析

时间:2024-07-01 12:30:50浏览次数:15  
标签:info typeid DemoBase 类型信息 Demo void var Fun

目录

这篇文章讨论一下C++中typeid以及type_info的用法。

一.环境

windows11,VS2022

二.基础用法

1.需要明确一下typeid是操作符,不是函数,就像sizeof。

2.typeid的操作对象可以是变量,可以是类型,也可以是常量。

3.使用typeid可以获取到type_info类型的数据,顾名思义,就是数据类型信息。

4.使用typeid允许获取运行时的类型。

5.代码示例

#include<iostream>
#include<typeinfo>

class Demo
{
public:
	Demo(void) = default;
	~Demo(void) noexcept = default;

private:

};

int main(int argc, char* argv[])
{
	int intVar = 10;
	Demo demo;

	auto& typeInfo = typeid(int);
	const type_info& typeInfo2 = typeid(20);

	std::cout << "typeInfo.name():" << typeInfo.name() << std::endl;
	std::cout << "typeInfo2.name():" << typeInfo2.name() << std::endl;
	std::cout << "typeid(Demo).name():" << typeid(Demo).name() << std::endl;
	std::cout << "typeid(demo).name():" << typeid(demo).name() << std::endl;

	if (typeid(int) == typeid(intVar))
	{
		std::cout << "==" << std::endl;
	}
	else
	{
		std::cout << "!=" << std::endl;
	}

	return 0;
}

很简单的代码,看一下运行的结果

在这里插入图片描述

type_info有多个成员函数以及支持的运算符,感兴趣可以打开IDE敲一敲。

三.编译期计算还是运行时计算

什么?上面不是有提到说允许使用typeid允许获取运行时的类型?这个问题不是很简单吗?当然是运行时了!那可不一定,写代码具体识别一下就知道了。

有个知识点我们都知道,那就是C++中模板的实例化是在编译期,所以模板参数需要在编译期确定。因此这里借助模板进行识别。

1.实验一

直接看代码

#include<iostream>
#include<typeinfo>

template<const type_info& typeInfo>
void Fun(void)
{
	std::cout << "typeInfo.name()" << typeInfo.name() << std::endl;
}

int main(int argc, char* argv[])
{
	int var = 10;
	int& qVar = var;
	int* pVar = &var;

	Fun<typeid(int)>();
	Fun<typeid(20)>();
	Fun<typeid(var)>();
	Fun<typeid(qVar)>();
	Fun<typeid(pVar)>();
	Fun<typeid(*pVar)>();

	return 0;
}

执行的结果

在这里插入图片描述

代码能够正确编译并且得到预期结果,说明对于基础类型,typeid操作对象是类型/常量/对象/引用/指针/指针的解引用,都是在编译期计算好的。

2.实验二

直接看代码

#include<iostream>
#include<typeinfo>

template<const type_info& typeInfo>
void Fun(void)
{
	std::cout << "typeInfo.name()" << typeInfo.name() << std::endl;
}

class DemoBase
{
public:
	DemoBase(void) = default;
	~DemoBase(void) noexcept = default;
};

class Demo : public DemoBase
{
public:
	Demo(void) = default;
	~Demo(void) noexcept = default;
};

int main(int argc, char* argv[])
{
	Demo var;
	DemoBase varBase;
	Demo& qVar = var;
	Demo* pVar = &var;
	DemoBase& qVarBase = var;
	DemoBase* pVarBase = &var;

	Fun<typeid(Demo)>();
	Fun<typeid(DemoBase)>();
	Fun<typeid(var)>();
	Fun<typeid(varBase)>();
	Fun<typeid(qVar)>();
	Fun<typeid(pVar)>();
	Fun<typeid(*pVar)>();
	Fun<typeid(qVarBase)>();
	Fun<typeid(pVarBase)>();
	Fun<typeid(*pVarBase)>();

	return 0;
}

执行的结果

在这里插入图片描述

代码同样可以正确编译,说明对于不包含虚函数的自定义类型,typeid操作对象是类型/对象/引用/指针/指针的解引用,也都是在编译期计算的。

3.实验三

继续看代码

#include<iostream>
#include<typeinfo>

template<const type_info& typeInfo>
void Fun(void)
{
	std::cout << "typeInfo.name()" << typeInfo.name() << std::endl;
}

class DemoBase
{
public:
	DemoBase(void) = default;
	virtual ~DemoBase(void) noexcept = default;
};

class Demo : public DemoBase
{
public:
	Demo(void) = default;
	virtual ~Demo(void) noexcept override = default;
};

int main(int argc, char* argv[])
{
	Demo var;
	DemoBase varBase;
	Demo& qVar = var;
	Demo* pVar = &var;
	DemoBase& qVarBase = var;
	DemoBase* pVarBase = &var;

	Fun<typeid(Demo)>();
	Fun<typeid(DemoBase)>();
	Fun<typeid(var)>();
	Fun<typeid(varBase)>();
	Fun<typeid(qVar)>();
	Fun<typeid(pVar)>();
	Fun<typeid(*pVar)>();
	Fun<typeid(qVarBase)>();
	Fun<typeid(pVarBase)>();
	Fun<typeid(*pVarBase)>();

	return 0;
}

这个时候就不一样了啊,发现代码报错了,不能正确编译

在这里插入图片描述

在这里插入图片描述

可以看到报错的是引用和指针的解引用。

说明对于包含虚函数的自定义类型,typeid操作对象是类型/对象/指针,是在编译期运算的,typeid操作对象是引用/指针的解引用,是在运行时计算的。

什么,是不是对于包含虚函数的自定义类型,typeid不能那么写?放心,写法是对的,不信可以试一下不要写在模板里。

四.用法展示

展示一个看起来比较鸡肋的用法,代码

#include<iostream>
#include<typeinfo>
#include<memory>

class DemoBase
{
public:
	DemoBase(void) = default;
	void Fun(void)
	{
		std::cout << "typeid(*this).name():" << typeid(*this).name() << std::endl;
	}
	virtual ~DemoBase(void) noexcept = default;
};

class Demo : public DemoBase
{
public:
	Demo(void) = default;
	virtual ~Demo(void) noexcept override = default;
};

int main(int argc, char* argv[])
{
	std::shared_ptr<DemoBase> p(new Demo());
	p->Fun();

	return 0;
}

执行结果

在这里插入图片描述

好像挺鸡肋对不对,但是即使真的鸡肋可能也会有一些合适的应用场景,感兴趣的话可以思考下。

五.其他

是不是也可以使用constexpr来识别是在编译期还是运行时计算,感兴趣的话可以试一下。

标签:info,typeid,DemoBase,类型信息,Demo,void,var,Fun
From: https://blog.csdn.net/2401_85919417/article/details/140076903

相关文章

  • C#winform如何在窗体实现视频播放
    1.在Form窗体设计中的左侧工具箱列表中右击鼠标,单击选择项。2.在弹出的对话框中点击COM组件,选择WindowsMediaPlayer,点击确定3.接着在工具箱选择WindowsMediaPlayer控件,将控件添加到窗体中,并且添加一个OpenFileDialog控件4.接着在工具箱的对话框中将OpenFileDialog添加......
  • Winform RichTextBox 获取Text文本中段落及区块
    在C#WinForms应用程序中,RichTextBox控件是一个功能强大的文本编辑控件,支持多种文本格式。如果你需要获取RichTextBox中每一部分的文本,包括段落和不同样式的区块,可以通过以下步骤实现。总体思路是使用RichTextBox的RichTextBox.Find以及RichTextBox.SelectionStart和RichTextBox.......
  • C# WinForm给ToolStrip工具栏扩展一个CheckBox单选框类型按钮的方法
    [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip)]publicpartialclassToolStripCheckBox:ToolStripItem{privateboolIsChecked=false;publicboolHasChecked{get......
  • 全面掌握 CrystalDiskInfo使用教程 的各项高级功能,实现专业级别的硬盘健康管理、性能
    CrystalDiskInfo的初级应用大纲:介绍:CrystalDiskInfo是一款免费的硬盘健康监测工具,可以帮助用户监测硬盘状态,预测故障,并提供警报通知。安装和启动:下载并安装CrystalDiskInfo软件;启动CrystalDiskInfo软件。界面导览:主界面介绍:显示硬盘信息、健康状态、温度......
  • 强化学习(Reinforcement Lrarning,RL)03:贝尔曼方程
    强化学习(ReinforcementLrarning,RL)03:贝尔曼方程强化学习(ReinforcementLrarning,RL)03:贝尔曼方程1.状态价值1.1状态价值函数(StateValueFunction)1.2最优策略(OptimalPolicy)2.贝尔曼方程2.1贝尔曼方程(BellmanEquation)2.2贝尔曼方程的推导2.3贝尔曼方程矩阵形式(Matr......
  • 强化学习(Reinforcement Lrarning,RL)02:马尔科夫决策过程
    强化学习(ReinforcementLrarning,RL)02:马尔科夫决策过程强化学习(ReinforcementLrarning,RL)02:马尔科夫决策过程状态与状态空间动作与动作空间策略函数状态转移与状态转移函数奖励轨迹回报与折扣回报一个重要性质强化学习(ReinforcementLrarning,RL)02:马尔科夫决策过程马......
  • C# Winform 开源UI库
        WinForms,作为微软.NET框架下的一个桌面应用程序开发工具,自1999年首次亮相以来,已经走过了二十多年的发展历程。它以其简单直观的拖拽式界面设计和丰富的控件库,成为了大众喜爱的入门学习编程工具。由于它是比较基础的开发工具,在UI上并没有做太多优化,所以设置出来的界......
  • 基于C#的winform和halcon开发的通用视觉框架,类似visionpro
    基于C#的winform和halcon开发的通用视觉框架界面风格和visionpro的很像,线条连线的流程风格,代码编译无报错,程序可运行,工具不是很完善,适合大家学习使用。需要源码请私信或者加QQ......
  • 基于C#的winform和halcon开发的通用视觉框架
    基于C#的winform和halcon开发的通用视觉框架代码编译无报错,程序可运行,有些地方有BUG,适合大家学习使用。需要源码请私信或者加QQ......
  • 【winform】ListBox如何给item项添加hover
    1、绑定move事件listBox1.MouseMove+=newMouseEventHandler(listBox_MouseMove);2、编写代码privatevoidlistBox_MouseMove(object?sender,MouseEventArgse){ListBox?listBox=senderasListBox;//获取鼠标在ListBox中的位置int......