分享

Boost::any分析

 weicat 2009-11-23
Boost::any分析收藏
 
boost::any是一个能代表任何对象类型的对象,正如COM库的Variant变量类型,以及JAVA中的Object。不同的是,Variant的做法是包含所有可能类型的一个成员实现,浪费空间,而则boost::any借助于模板,没有空间浪费。
Variant的大致实现是:
Class Cvariant
{
       int   iData;
         long lData;
       ….
       Int   type;
}
而boost::any则使用模板,依靠两个内部类来封装实际数据(PlaceFolder和Folder),并对外暴露一个叫做Type()的函数暴露实际数据的类型。
为了方便分析其代码,现展示一个简单的测试代码:
#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库。)如下所示:
    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源代码的关键部分,其实很短小,但是,功能上非常强大,特别是在配合容器使用时。
 
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chalichen/articles/365470.aspx

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多