boost::any是一个能代表任何对象类型的对象,正如COM库的Variant变量类型,以及JAVA中的Object。不同的是,Variant的做法是包含所有可能类型的一个成员实现,浪费空间,而则boost::any借助于模板,没有空间浪费。
Variant的大致实现是:
Class Cvariant
{
int iData;
long lData;
….
int type;
}
而boost::any则使用模板,依靠两个内部类来封装实际数据(PlaceFolder和Folder ),并对外暴露一个叫做Type()的函数暴露实际数据的类型。
为了方便分析其代码,现展示一个简单的测试代码:
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
#include "stdafx.h"
#include <iostream>
#include <list>
#include "boost/any.hpp"
typedef std::list<boost::any> list_any;
// 关键部分:可以存放任意类型的对象
void fill_list(list_any& la)
{
// 存放常数
la.push_back(10);
// 存放字符串对象
la.push_back( std::string( "dyunze" ) );
// 注意 la.push_back(“dyunze”) 错误,因为会被当错字符串数组
}
// 根据类型进行显示:
void show_list(list_any& la)
{
list_any::iterator it;
boost::any anyone;
for ( it = la.begin(); it != la.end(); it++ )
{
anyone = *it;
if ( anyone.type() == typeid ( int ) )
std::cout<<boost::any_cast< int >(*it)<<std::endl;
else if ( anyone.type() == typeid (std::string) )
std::cout<<boost::any_cast<std::string>(*it).c_str()<<std::endl;
}
}
// 主程序部分:
int main( int argc, char * argv[])
{
list_any la;
fill_list(la);
show_list(la);
return 0;
}
以下是我整理了后的boost::any的关键代码,( 只是为了说明,可能无法直接运行,如需要完整代码,请到www.boost.org下载boost库。 )如下所示:
- class any
- {
- public :
- //模板构造函数,参数可以是任意类型,真正的数据保存在content中
- template < typename ValueType>
- any(const ValueType & value): content( new holder<ValueType>(value))
- {
- }
- //析构函数,删除保存数据的content对象
- ~any()
- {
- delete content;
- }
- //一个placeholde对象指针,只想其子类folder的一个实现
- // 即content( new holder<ValueType>(value) )语句
- placeholder * content;
- public :
- //查询真实数据的类型,拆葙时有用。
- const std::type_info & type() const
- {
- return content ? content->type() : typeid ( void );
- }
- /**一个稻草人,存在好处是没有模板参数,可以直接申明,
- *如: placeholder * content;
- *如果使用子类folder类,则这能用older<Type>
- *content,而申明时Type还不确定
- */
- class placeholder
- {
- public :
- virtual ~placeholder()
- {
- }
- public :
- virtual const std::type_info & type() const = 0;
- virtual placeholder * clone() const = 0;
- };
- //真正保存和获取数据的类。
- template < typename ValueType>
- class holder : public placeholder
- {
- public :
- holder(const ValueType & value)
- : held(value)
- {
- }
- public :
- virtual const std::type_info & type() const
- {
- return typeid (ValueType);
- }
- virtual placeholder * clone() const
- {
- return new holder(held);
- }
- public :
- //真正的数据,就保存在这里
- ValueType held;
- };
- };
- /**
- *获取content->helder数据的方法。
- *
- */
- template < typename ValueType>
- ValueType * any_cast(any * operand)
- {
- return operand && operand->type() == typeid (ValueType) ? & static_cast <any::holder<ValueType> *>(operand->content)->held : 0;
- }
以上就是boost::any源代码的关键部分,其实很短小,但是,功能上非常强大,特别是在配合容器使用时。