Boost.Any 源码解析

待解决的问题

  • 当同一个 X( 变量/返回值/参数) 需要在接纳不同类型的数据的时候。
Any a ;
a = 1 ;
// ... do something with a 
a = "1";
// ... do something with a 
  • 当不同类型(不来自同一个继承体系)的对象需要被视为统一类型的时候。(比如放入同一个容器)
std::array<Any,2> data;
data[0]=1;
data[1]="1";

传统的解决方案

void * 
传统解决方案的不足
  • 丢失类型信息
void * ret = new A() ;
assert(typeid(ret) == (new A())); // assert failed !
  • 容易引入内存问题,未定义问题
void * base  = new A() ;
B * now = static_cast<B*>(base); // undefined behavior ...

实现Any需要解决的问题

1. 如何在不丢失类型的情况下任意存储数据
2. 如何安全的,动态的 [ 设置/删/改/查 ] 数据

Boost.Any 源码解析

boost 版本号 :1.54
我对代码顺序进行了简单的调整, 删除了和核心无关的支持c++11的右值接口和friend 关键字相关代码。

1. 如何在不丢失类型的情况下任意存储数据
    // 存储抽象接口,支持返回类型和克隆自身.
    // void * 的替代品 --> placeholder *
    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;

        private: // intentionally left unimplemented
            holder & operator=(const holder &);
        };
2. 如何安全的,动态的 [ 设置/删/改/查 ] 数据
// 代码顺序略有调整
class any
    {
    public: 
        placeholder * content; // 指向实际存储数据
    public: // structors
    // 一系列构造函数 ...
        any() BOOST_NOEXCEPT
          : 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)
        {
        }
        // 析构函数 , delete 0 真的好么 ?       
        ~any() BOOST_NOEXCEPT
        {
            delete content;
        }

    public: // modifiers
    // swap 接口,直接互换数据内存.
        any & swap(any & rhs) BOOST_NOEXCEPT
        {
            std::swap(content, rhs.content);
            return *this;
        }
        // = 运算符
        // 由于any 可以由任意类型参数默认构造 , 所以这个接口进化为 Any a = 任意对象。
        any & operator=(const any& rhs)
        {
            any(rhs).swap(*this);
            return *this;
        }

    public: // queries
    // 是否被设置过。
        bool empty() const BOOST_NOEXCEPT
        {
            return !content;
        }
    // 但前的类型信息.
        const std::type_info & type() const
        {
            return content ? content->type() : typeid(void);
        }
};
// 获取存储的数据指针, 注意此时传入的any的指针
template<typename ValueType>
    ValueType * any_cast(any * operand) BOOST_NOEXCEPT
    {
        return operand && 
            operand->type() == typeid(ValueType)
            ? &static_cast<any::holder<ValueType> *>(operand->content)->held
            : 0;
    }
// 获取const的存储的数据指针,
    template<typename ValueType>
    inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
    {
        return any_cast<ValueType>(const_cast<any *>(operand));
    }
// 获取一个存储内容的拷贝 , 注意参数是引用
    template<typename ValueType>
    ValueType any_cast(any & operand)
    {
        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;

        nonref * result = any_cast<nonref>(&operand);
        if(!result)
            boost::throw_exception(bad_any_cast());
        return *result;
    }
// const 版本获得拷贝.
    template<typename ValueType>
    inline ValueType any_cast(const any & operand)
    {
        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
        return any_cast<const nonref &>(const_cast<any &>(operand));
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值