• 任意类型对象Any


    一个对象可以是任意类型,类似于同台语言的变量

    any.h:

    /*
    * any.h
    *
    * Created on: 2012-3-31
    * Author: vivence
    */

    #ifndef ANY_H_
    #define ANY_H_

    #include <utility>

    namespace ghost{

    class Any{
    class HolderBase{
    public:
    virtual ~HolderBase(){}
    virtual HolderBase* Clone() = 0;
    };
    template<typename T>
    class Holder : public HolderBase{
    T obj_;
    public:
    explicit Holder(const T& t) : obj_(t){}
    explicit Holder(T&& t) : obj_(std::move(t)){}

    public:
    virtual HolderBase* Clone()
    {
    return new Holder<T>(obj_);
    }

    public:
    void Set(const T& t)
    {
    obj_ = t;
    }
    void Set(T&& t)
    {
    obj_ = std::move(t);
    }

    T& Get()
    {
    return obj_;
    }
    const T& Get() const
    {
    return obj_;
    }
    };
    HolderBase* pHolder_;

    public:
    Any() : pHolder_(0){}
    template<typename T>
    explicit Any(const T& t) : pHolder_(new Holder<T>(t)){}
    template<typename T>
    explicit Any(T&& t) : pHolder_(new Holder<T>(std::move(t))){}

    ~Any()
    {
    if (pHolder_)
    {
    delete pHolder_;
    }
    }

    Any(const Any& rhs)
    : pHolder_(0)
    {
    if (rhs.pHolder_)
    {
    pHolder_ = rhs.pHolder_->Clone();
    }
    }
    Any(Any&& rhs)
    : pHolder_(rhs.pHolder_)
    {
    rhs.pHolder_ = 0;
    }
    Any& operator =(const Any& rhs)
    {
    Any(rhs).Swap(*this);
    return *this;
    }
    Any& operator =(Any&& rhs)
    {
    Any(std::move(rhs)).Swap(*this);
    return *this;
    }
    void Swap(Any& rhs)
    {
    std::swap(pHolder_, rhs.pHolder_);
    }

    public:
    template<typename T>
    void Set(const T& t)
    {
    Holder<T>* pTHolder = dynamic_cast<Holder<T>*>(pHolder_);
    if (pTHolder)
    {
    pTHolder->Set(t);
    }
    else
    {
    if (pHolder_)
    {
    delete pHolder_;
    }
    pHolder_ = new Holder<T>(t);
    }
    }
    template<typename T>
    void Set(T&& t)
    {
    Holder<T>* pTHolder = dynamic_cast<Holder<T>*>(pHolder_);
    if (pTHolder)
    {
    pTHolder->Set(std::move(t));
    }
    else
    {
    if (pHolder_)
    {
    delete pHolder_;
    }
    pHolder_ = new Holder<T>(std::move(t));
    }
    }

    public:
    struct NotHoldThisType{};
    template<typename T>
    T& Get() throw(NotHoldThisType)
    {
    Holder<T>* pTHolder = dynamic_cast<Holder<T>*>(pHolder_);
    if (pTHolder)
    {
    return pTHolder->Get();
    }
    else
    {

    throw NotHoldThisType();
    }
    }
    template<typename T>
    const T& Get() const throw(NotHoldThisType)
    {
    const Holder<T>* pTHolder = dynamic_cast<const Holder<T>*>(pHolder_);
    if (pTHolder)
    {
    return pTHolder->Get();
    }
    else
    {

    throw NotHoldThisType();
    }
    }
    };

    } // namespace ghost

    #endif /* ANY_H_ */


    test.cpp:

    /*
    * test.cpp
    *
    * Created on: 2012-3-9
    * Author: vivence
    */

    #include "variant.h"
    #include "any.h"
    #include <iostream>
    #include <iomanip>
    #include <string>

    int main()
    {
    ghost::Variant<int, bool, char> testVariant;
    testVariant.Set(1);
    testVariant.Set(false);
    testVariant.Set('a');
    testVariant.Set('b');
    std::cout<<testVariant.Get<int>()<<std::endl;
    std::cout<<std::boolalpha<<testVariant.Get<bool>()<<std::endl;
    std::cout<<testVariant.Get<char>()<<std::endl;

    ghost::Any testAny(1);
    try
    {
    std::cout<<testAny.Get<int>()<<std::endl;
    }
    catch(ghost::Any::NotHoldThisType& e)
    {
    std::cerr<<"testAny is not int\n";
    }
    testAny.Set(std::string("test"));
    try
    {
    std::cout<<testAny.Get<std::string>()<<std::endl;
    }
    catch(ghost::Any::NotHoldThisType& e)
    {
    std::cerr<<"testAny is not string\n";
    }
    return 0;
    }



  • 相关阅读:
    ajax
    cookie
    JavaScript基本语法
    HTML css 格式布局
    HTML 表单
    html 一般标签 常用标签 表格
    WinForm——操作word文档
    WinForm进程 线程
    音乐
    注册 传值
  • 原文地址:https://www.cnblogs.com/EvilGhost/p/any.html
Copyright © 2020-2023  润新知