boost::any类型实现原理

本文详细介绍了Boost库中any类型的实现原理,通过继承和多态的方式实现了一个泛型的union类型,能够安全地存储任意类型的数据,并提供了类型信息的获取方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

boost::any是一种通用类型,可以存放任意值。

问题:通用类型any如何存放任意值?

A: 这里的通用类型类似于脚本语言中的类型。
方案一, union结构体:但union只能存放固定种类的值,没有扩展性。
方案二, void *类型: C++是强类型语言,用void *保存后丢失了类型信息,很难保证类型安全。
方案三, 模板: 模板需要参数化,any<int> = 1; any<double> = 1.0; any<X> = x; 显然这不能满足要求。
方案四, 继承和多态,即boost::any类的实现方法。any类存放一placeholder的指针,
 而holder是一继承placeholder的模板,模板是拥有类型信息的,因此可以保证类型安全。

废话少说,直接上原理实现代码的demo。

class any
{
public:
	//Representation and basic construction of a generalized union type.
	any(): content(0)
	{
	}

	~any()
	{
		delete content;
	}
	
	//获得类型信息
	const std::type_info &type_info() const 
	{
		return content ? content->type_info() : typeid(void);
	}

	//INWARD CONVERSIONS 
	any(const any &other) : content(other.content ? other.content->clone() : 0)
	{
	}

	template<typename value_type>
	any(const value_type &value) : content(new holder<value_type>(value)) //函数模板
	{
	}
	
	any &swap(any &rhs)
	{
		std::swap(content, rhs.content);
		return *this;
	}

	any &operator=(const any &rhs)
	{
		return swap(any(rhs)); //利用拷贝构造函数创建局部变量作为参数传给swap,交换值之后,局部变量自动销毁,而rhs值不变;
	}

	template<typename value_type>
	any &operator=(const value_type &rhs) //函数模板
	{
		return swap(any(rhs));
	}
	
	//OUTWARD CONVERSIONS
	operator const void *() const
	{
		return content;
	}

	template<typename value_type>
	bool copy_to(value_type &value) const
	{
		const value_type *copyable = to_ptr<value_type>();
		if(copyable)
			value = *copyable;
		return copyable;
	}

	template<typename value_type>
	const value_type *to_ptr() const
	{
		return type_info() == typeid(value_type)? //判断类型是否相同
			&static_cast<holder<value_type> *>(content)->held : 0;
	}

private:
	class placeholder
	{
	public:
		virtual ~placeholder()
		{
		}
		virtual const std::type_info & type_info() const = 0; //获得类型
		virtual placeholder *clone() const = 0; //获得值拷贝
	};

	template<typename value_type>
	class holder : public placeholder
	{
	public:
		holder(const value_type &value)	: held(value)
		{
		}

		virtual const std::type_info &type_info() const 
		{
			return typeid(value_type);
		}

		virtual placeholder *clone() const
		{
			return new holder(held);
		}

		const value_type held;//存储值
	};

	placeholder *content;
};

template<typename value_type>
value_type any_cast(const any &operand)
{
	const value_type *result = operand.to_ptr<value_type>();
	
	//return result ? *result : throw std::bad_cast(); //有异常,原因未知,将来再分析
	if (result)
		return *result;
	throw std::bad_cast();
}

int main(int argc, char* argv[])
{
	any i_a = 3;
	int i_b = any_cast<int>(i_a);	
	std::cout<<i_a<<"\t"<<i_b<<std::endl;
	
	any s_a = std::string("demo");
	std::string s_b = any_cast<std::string>(s_a);
	std::cout<<s_a<<"\t"<<s_b<<std::endl;

	return 0;
}

参考文献:

1, http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf

2, http://stlchina.huhoo.net/twiki/bin/view.pl/Main/BoostSource_any

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值