Any类的实现

4 篇文章 0 订阅

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

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

#include <boost/any.hpp>
#include <vector>

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

std::vector<boost::any> v;
v.push_back(s);
v.push_back(b);

int va = boost::any_cast<string>(s);
int vb = boost::any_cast<double>(b);

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

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

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

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

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

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

如何转换成原始类型呢?

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

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

	struct Base;
	typedef std::unique_ptr<Base> BasePtr;//智能指针管理对象的生命周期。

	struct Base
	{
		virtual ~Base() {}
		virtual BasePtr Clone() const = 0;
	};

	template<typename T>//赋值的相关类型
	struct Derived : Base
	{
		template<typename U>
		Derived(U && value) : m_value(std::forward<U>(value)) { }

		BasePtr Clone() const
		{//赋值时,将创建的派生类对象赋值给基类指针。
			return BasePtr(new Derived<T>(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<string>();//转换正确,将值赋值给s2,失败抛出异常。
	cout << "s2 = " << s2 << endl;
	bool ret1 = any2.IsNull();//转换以后为0,为转换之前为1
	bool r = any2.Is<string>  //看是否转成对应的类型。
	cout << "testany()" << "ret1 = " << ret1 << "r = " << r << endl;
}

在这里插入图片描述

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值