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

Any类的实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Any类的实现

首先说一下什么Any类呢?
从英文名可以看出就是任何的意思,一般对象都是各个类型的,通过这个Any可以让各个对象的类型全部擦除,也就是将一个对象的类型先消除,等到用到 的时候再将对应的类型赋值。

boost库中也又Any类,先不说这个,想要的可以自行百度。
以下是一个简单的例子

#include 
#include 

boost::any s= "test";
boost::any b = 2.5;

std::vector v;
v.push_back(s);
v.push_back(b);

int va = boost::any_cast(s);
int vb = boost::any_cast(b);

关键点:
any能够容纳所有类型的数据,当赋值给any的时候需要将值的类型擦除,以通用的方式保存所有类型的数据。

如何能够将擦除的类型保存起来呢?

可以通过继承擦除类型,基类是不包含模板参数的,派生类中才有模板参数,这个模板参数正是赋值的类型。

赋值时,将创建的派生类对象赋值给基类指针。

基类的派生来携带了数据类型,基类只是原始数据的一个占位符,通过多态的隐式转换擦除了原始数据的类型。

因此,任何数据类型都能赋值给它,从而能实现存放所有的类型。

如何转换成原始类型呢?

取数据的时候需要向下转换成派生类来获取原始数据,当转换失败时,打印详情,抛出异常。

给Any赋值的时候,还要管理该对象的生命周期,所以用只能指针来管理。

	struct base;
	typedef std::unique_ptr basePtr;//智能指针管理对象的生命周期。

	struct base
	{
		virtual ~base() {}
		virtual basePtr Clone() const = 0;
	};

	template//赋值的相关类型
	struct Derived : base
	{
		template
		Derived(U && value) : m_value(std::forward(value)) { }

		basePtr Clone() const
		{//赋值时,将创建的派生类对象赋值给基类指针。
			return basePtr(new Derived(m_value));
		}

		T m_value;
	};

	basePtr Clone() const
	{
		if (m_ptr != nullptr)
			return m_ptr->Clone();

		return nullptr;
	}

	basePtr m_ptr;
	std::type_index m_tpIndex;

接下来看看实际调用的例子:

void TestAny()
{
	string s1 = "hello";

	Any any2;
	any2 = s1;	
	string s2 = any2.AnyCast();//转换正确,将值赋值给s2,失败抛出异常。
	cout << "s2 = " << s2 << endl;
	bool ret1 = any2.IsNull();//转换以后为0,为转换之前为1
	bool r = any2.Is  //看是否转成对应的类型。
	cout << "testany()" << "ret1 = " << ret1 << "r = " << r << endl;
}

在c++中,typeid用于返回指针或引用所指对象的实际类型。

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

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号