[转]boost::any的用法、优点和缺点以及源代码分析

[转]boost::any的用法、优点和缺点以及源代码分析

2023年8月2日发(作者:)

[转]boost::any的⽤法、优点和缺点以及源代码分析boost::any⽤法⽰例:#include #include #include typedef std::list list_any;//关键部分:可以存放任意类型的对象void fill_list(list_any& la){

_back(10);//存放常数

_back( std::string("dyunze") );//存放字符串对象;注意_back(“dyunze”)错误,因为会被当错字符串数组}//根据类型进⾏显⽰void show_list(list_any& la){ list_any::iterator it; boost::any anyone; for( it = (); it != (); it++ ) {

anyone = *it; if( () == 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类及其基类placeholder3)获取真正数据的模板函数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(t ? t->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数据的⽅法。⽤来获取真正的数据templateValueType any_cast(const any& operand){ assert( () == typeid(ValueType) ); return static_cast *>(t)->held;}//下代码是使⽤⽰例typedef std::list list_any;void fill_list(list_any& la){

_back(10);//存放常数;调⽤了any的模板构造函数,下同 _back( std::string("我是string") );//存放字符串对象;注意_back(“dyunze”)错误,因为会被当错字符串数组 char* p = "我是常量区字符串abc"; _back(p);//可以存放指针,但要注意指针的失效问题}//根据类型进⾏显⽰void show_list(list_any& la){ list_any::iterator it; for( it = (); it != (); it++ ) {

if( (*it).type() == typeid(int) ) std::cout<(*it)<(*it).c_str()<(*it)<

发布者:admin,转转请注明出处:http://www.yc00.com/news/1690907064a460312.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信