Boost 学习 ――Any篇

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;
       }
}
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

Boost 学习 ――Any篇

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭