任意类型对象Any

it2022-05-09  23

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

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;}

转载于:https://www.cnblogs.com/EvilGhost/archive/2012/03/31/any.html


最新回复(0)