专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
boost::any的用法、优点和缺点以及源代码分析
2019-04-14 20:08
发布
生成海报
站内文章
/
模拟电子
15983
0
1212
boost::any用法示例:
#include
#include
#include
typedef std::list
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<
(*it)<
(*it).c_str()<
boost::any的优点:
对设计模式理解的朋友都会知道合成模式。因为多态只有在使用指针或引用的情况下才能显现,所以std容器中只能存放指针或引用(
但实际上只能存放指针
,无法存放引用,这个好像是c++的不足吧)。如: std::list
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
#include
#include
//自定义的any类 class any { public: //保存真正数据的接口类 class placeholder { public: virtual ~placeholder() { } public: virtual const std::type_info & type() const = 0; virtual placeholder * clone() const = 0; }; //真正保存和获取数据的类。 template
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
any(const ValueType & value): content(new holder
(value)) { } //拷贝构造函数 any(const any & other) : content(other.content ? other.content->clone() : 0) { } //析构函数,删除保存数据的content对象 ~any() { if(NULL != content) delete content; } private: //一个placeholde对象指针,指向其子类folder的一个实现 // 即content( new holder
(value) )语句 placeholder* content; template
friend ValueType any_cast(const any& operand); public: //查询真实数据的类型。 const std::type_info & type() const { return content ? content->type() : typeid(void); } }; //获取content->helder数据的方法。用来获取真正的数据 template
ValueType any_cast(const any& operand) { assert( operand.type() == typeid(ValueType) ); return static_cast
*>(operand.content)->held; } //下代码是使用示例 typedef std::list
list_any; void fill_list(list_any& la) { la.push_back(10);//存放常数;调用了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<
(*it)<
(*it).c_str()<
(*it)<
参考文献: 1)
http://www.nohack.cn/code/other/2006-10-05/10230.html
2)boost::any源代码
Ta的文章
更多
>>
boost::any的用法、优点和缺点以及源代码分析
0 个评论
热门文章
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮