boost::any用法示例:

#include <iostream>
#include <list>
#include <boost/any.hpp> typedef std::list<boost::any> list_any; //关键部分:可以存放任意类型的对象
void fill_list(list_any& la)
{
la.push_back();//存放常数
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()
{
list_any la;
fill_list(la);
show_list(la); return ;
}

boost::any的优点:

对设计模式理解的朋友都会知道合成模式。因为多态只有在使用指针或引用的情况下才能显现,所以std容器中只能存放指针或引用(但实际上只能存放指针,无法存放引用,这个好像是c++的不足吧)。如:

std::list<BaseClass*> mylist;

这样,我们就要对指针所指向内容的生存周期操心(可能需要程序员适时删除申请的内存;但是由于存放指针,插入/删除的效率高),而使用boost::any就可能避免这种情况,因为我们可以存放类型本身(当然存放指针也可以)。这是boost::any的优点之一。

boost::any另一个优点是可以存放任何类型。而前面提到的mylist只能存放BaseClass类指针以及其继承类的指针。

boost::any的缺点:

由于boost::any可以存放任何类型,自然它用不了多态特性,没有统一的接口,所以在获取容器中的元素时需要实现判别元素的真正类型,这增加了程序员的负担。与面向对象编程思想有些矛盾,但整个标准c++模板库何尝不是如此,用那些牛人的话来说,是“有益补充”。

总之,有利必有弊,没有十全十美的。

分析并模仿boost::any:

读了一下boost::any的源代码,并模仿一下其实现(相当一部分时拷贝原代码),下面是代码(只包含必要功能)。

实现any的功能主要由三部分组成:
1)any类
2)真正保存数据的holder类及其基类placeholder
3)获取真正数据的模板函数any_cast,类型转换的功能。

#include <iostream>
#include <list>
#include <cassert> //自定义的any类
class any
{
public: //保存真正数据的接口类
class placeholder
{
public:
virtual ~placeholder()
{
}
public: virtual const std::type_info & type() const = ;
virtual placeholder * clone() const = ;
}; //真正保存和获取数据的类。
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;
}; public: any(): content(NULL)
{
} //模板构造函数,参数可以是任意类型,真正的数据保存在content中
template<typename ValueType>
any(const ValueType & value): content(new holder<ValueType>(value))
{
} //拷贝构造函数
any(const any & other)
: content(other.content ? other.content->clone() : )
{
} //析构函数,删除保存数据的content对象
~any()
{
if(NULL != content)
delete content;
} private:
//一个placeholde对象指针,指向其子类folder的一个实现
// 即content( new holder<ValueType>(value) )语句
placeholder* content; template<typename ValueType> friend ValueType any_cast(const any& operand);
public: //查询真实数据的类型。
const std::type_info & type() const
{
return content ? content->type() : typeid(void);
}
}; //获取content->helder数据的方法。用来获取真正的数据
template<typename ValueType>
ValueType any_cast(const any& operand)
{
assert( operand.type() == typeid(ValueType) );
return static_cast<any::holder<ValueType> *>(operand.content)->held;
} //下代码是使用示例 typedef std::list<any> list_any; void fill_list(list_any& la)
{
la.push_back();//存放常数;调用了any的模板构造函数,下同
la.push_back( std::string("我是string") );//存放字符串对象;注意la.push_back(“dyunze”)错误,因为会被当错字符串数组 char* p = "我是常量区字符串abc";
la.push_back(p);//可以存放指针,但要注意指针的失效问题
} //根据类型进行显示
void show_list(list_any& la)
{
list_any::iterator it; for( it = la.begin(); it != la.end(); it++ )
{ if( (*it).type() == typeid(int) )
std::cout<<any_cast<int>(*it)<<std::endl;
else if( (*it).type() == typeid(std::string) )
std::cout<<any_cast<std::string>(*it).c_str()<<std::endl;
else if( (*it).type() == typeid(char*) )
std::cout<<any_cast<char*>(*it)<<std::endl;
}
} int main()
{
list_any la;
fill_list(la);
show_list(la); return ;
}

参考文献

1)http://www.nohack.cn/code/other/2006-10-05/10230.html

2)boost::any源代码

[转] boost::any的用法、优点和缺点以及源代码分析的更多相关文章

  1. boost::function的用法

    本片文章主要介绍boost::function的用法. boost::function 就是一个函数的包装器(function wrapper),用来定义函数对象. 1.  介绍 Boost.Func ...

  2. 转:RTMPDump源代码分析

    0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...

  3. 转:ffdshow 源代码分析

    ffdshow神奇的功能:视频播放时显示运动矢量和QP FFDShow可以称得上是全能的解码.编码器.最初FFDShow只是mpeg视频解码器,不过现在他能做到的远不止于此.它能够解码的视频格式已经远 ...

  4. hostapd源代码分析(二):hostapd的工作机制

    [转]hostapd源代码分析(二):hostapd的工作机制 原文链接:http://blog.csdn.net/qq_21949217/article/details/46004433 在我的上一 ...

  5. Android应用程序绑定服务(bindService)的过程源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6745181 Android应用程序组件Serv ...

  6. Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6664554 在上一文章Android系统匿名共 ...

  7. JAVA随笔篇一(Timer源代码分析和scheduleAtFixedRate的使用)

    写完了基础篇,想了非常久要不要去写进阶篇.去写JSP等等的用法.最后决定先不去写.由于自己并非JAVA方面的大牛.眼下也在边做边学,所以决定先将自己不懂的拿出来学并记下来. Timer是Java自带的 ...

  8. ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  9. Java集合系列之TreeMap源代码分析

    一.概述 TreeMap是基于红黑树实现的.因为TreeMap实现了java.util.sortMap接口,集合中的映射关系是具有一定顺序的,该映射依据其键的自然顺序进行排序或者依据创建映射时提供的C ...

随机推荐

  1. Objective-C学习篇06—NSString与NSMutableString

    NSString OC提供了定义字符串对象的方法,也就是将想要表达的字符串用一对双引号引起来,并在开头加上@.@是OC中的指令符,它告诉编译器@以后的内容为OC中的语法.比如@”Harbingwang ...

  2. css margin collapse

    css中存在margin collapse,即边界塌陷或边界重叠. http://www.w3cplus.com/css/understanding-bfc-and-margin-collapse.h ...

  3. UITextField AutoComplete iOS输入框内文本自动完成

    当你打开Safari的时候,输入网址,会有许多候选网址,点击后,自动填充到输入框,进入网页. 打开词典查单词的时候,输入前面部分字母,软件会给出符合的候选单词. 这样做的目的,是为了省去用户繁琐的输入 ...

  4. 妙用git rebase --onto指令

    有时候,在分支提交更改的时候,会忘记rebase,就直接提交上去,或者忘记和本地远程分支做merge,就直接rebase了别的分支.有时候真希望有一种切片的方式,让自己的分支只需要接上某一段.这个时候 ...

  5. 初涉JavaScript模式 (2) : 基本技巧

    尽量少用全局变量 大量使用全局变量会导致的后果 全局变量创建以后会在整个JavaScript应用和Web页面中共享.所有的全局变量都存在于一个全局命名空间内,很容易发生冲突 不知不觉创建了全局变量 其 ...

  6. debian小巧好看的桌面

    先看完,不然,你一定会后悔的..不好看,你打我.. sudo apt-get install xfce4 sudo apt-get install xfce4-goodies sudo apt-get ...

  7. 习题二:string数组应用

    说明: 读字符串char buf[100]="xxx:yyy:zzz:aaa:bbb" 按“:”进行分解到string数组中去 逻辑: 通过指针遍历整个字符串 遇到'\0'表示字符 ...

  8. 《FPGA零基础入门到精通视频教程》-第001b讲软件的破解

    高清视频和配套讲义这里下载 http://www.fpgaw.com/thread-68128-1-1.html 优酷视频地址,不是很清楚

  9. OSSEC集合

    http://dcid.me/blog/2010/01/using-ossec-for-the-forensic-analysis-of-log-files/

  10. MySQL AB复制

    http://tonychiu.blog.51cto.com/656605/326541