Boost 学习 ――Any篇boost::any — 他的对象,可以容纳任何满足值类型(ValueType)的类型的对象。J(谁在忽悠呢?)ValueType 要求:代码分析:class any{public: // structors any() : content(0) { } template<typename ValueType> any(const ValueType & value) : content(new holder<ValueType>(value)) {} any(const any & other) : content(other.content ? other.content->clone() : 0) {} ~any() //Releases any and all resources used in management of instance { delete content; }public: // modifiers any & swap(any & rhs) { std::swap(content, rhs.content); //目的是交换content指针 return *this; } template<typename ValueType> any & operator=(const ValueType & rhs) { any(rhs).swap(*this); return *this; } any & operator=(const any & rhs) { any(rhs).swap(*this); return *this; } public: // queries bool empty() const //true if instance is empty { return !content; //学习,学习,如此简洁的代码 } const std::type_info & type() const { return content ? content->type() : typeid(void); }public: //内部代理类 class placeholder { public: // structors virtual ~placeholder() { } public: // queries virtual const std::type_info & type() const = 0; virtual placeholder * clone() const = 0; }; template<typename ValueType> class holder : public placeholder { public: // structors holder(const ValueType & value) : held(value) { } public: // queries virtual const std::type_info & type() const { return typeid(ValueType); } virtual placeholder * clone() const { return new holder(held); } public: // representation ValueType held; //实际的数据,它被包了两层外衣。 }; public: // representation (public so any_cast can be non-friend) placeholder * content;//指向容纳ValueType对象的指针};转型代码:template<typename ValueType>ValueType * any_cast(any * operand){ return operand && operand->type() == typeid(ValueType) ? &static_cast<any::holder<ValueType> *>(operand->content)->held : 0;} template<typename ValueType>const ValueType * any_cast(const any * operand){ return any_cast<ValueType>(const_cast<any *>(operand));} template<typename ValueType>ValueType any_cast(const any & operand){ const ValueType * result = any_cast<ValueType>(&operand); if(!result) throw(bad_any_cast()); return *result;}用处:1:在通常情况下,我们一个容器只能容纳一种类型,或者一种类型继承体系。一直如此,但是可以通过包一层解决这个问题。Any 是所有类型的衣衫,所有类型的对象穿上他之后,就成了any ,而存储any类型的容器,当然可以存储any对象,而不用管 any内部存储的是什么内容。2: 这个世界就剩下一种类型了。内存布局:下面图示了两种类型,int,string。
实际测试:
#include <iostream>#include <string>#include "Any.hpp" using namespace std;int main(){ string str("I believe i can fly."); any test(str); int t; try { t = any_cast<int>(test); } catch(bad_any_cast& exp) { std::cout<<exp.what() <<endl; } any inta(5);test.swap(inta);//将存储string内容的any 和int 类型的any 交换内容。J try { t = any_cast<int>(test); } catch(bad_any_cast& exp) { std::cout<<exp.what() <<endl; }}
本文地址:http://com.8s8s.com/it/it22183.htm