任意类型容器Any

利用模板类继承非模板类,实现一个可以存储任意类型的容器

 
#ifndef _ANY_H_
#define _ANY_H_
#include <string>
#include <algorithm>

class IAnyItem
{
public:
	virtual ~IAnyItem() {}
	virtual const std::type_info& type() const = 0;
	virtual bool  empty() const = 0;
	virtual IAnyItem* clone() const = 0;
};
 
class Any;
template<typename T>
class	AnyItem : public IAnyItem
{
private:
	AnyItem(const AnyItem<T>& x):elementNum(x.elementNum) {
		value = new T(*x.value);
	}
	AnyItem(const AnyItem<T>& x, size_t ele): elementNum(ele) {
		value = new T[elementNum]();
		memcpy(value, x.value, sizeof(T) * elementNum);
	}
	AnyItem():value(nullptr),elementNum(0) {}
	AnyItem(T val[], size_t n): elementNum(n) {
		value = new T[elementNum]();
		memcpy(value, val, sizeof(T) * n);
	}
	AnyItem(const T& val):elementNum(0) {
		value = new T(val);
	}

	virtual ~AnyItem() {
		if (value) {
			if(elementNum > 0) {
				delete[] value;
			}else {
				delete value;
			}
			value = nullptr;
		}
	}
	virtual const std::type_info& type() const{
		return typeid(T);
	}
 
	virtual bool	empty() const{
		return value == nullptr;
	}

	virtual IAnyItem* clone() const {
		IAnyItem* item = nullptr;
		if(elementNum > 0) {
			item = new AnyItem<T>(*this, elementNum);
		}else {
			item = new AnyItem<T>(*this);
		}
		
		return item;
	}
 
	const T& get() const {
		return *value;
	}

	T& ref() {
		return *value;
	}
	
	AnyItem operator=(const T& val) {
		*value = val;
		return *this;
	}
public:
	friend class Any;
private:
	T*		value;
	size_t 	elementNum;  // 当类型是数组类型是有效 元素个数
};
 
class	Any
{
public:
	Any():item(nullptr){}
	template<typename T>
	Any(const T& val):item(new AnyItem<T>(val)){}
	template<typename T>
	Any(T val[], size_t n):item(new AnyItem<T>(val, n)){} // 数组类型需要传递元素个数
	template<typename T>
	Any(const AnyItem<T>& x) {
		item = x.clone();
	}
	Any(const char* x):item(new AnyItem<std::string>(x)){}
	Any(char* x):item(new AnyItem<std::string>(x)){}
	Any(Any&& x):item(x.item) {
		x.item = nullptr;
	}
	Any(const Any& x):item(nullptr){
		if (x.getItem()) {
			item = x.getItem()->clone();
		}
	}
	~Any() {
		if (item) {
			delete item;
		}
	}

	template<typename T>
	const T& any_cast() const {
		AnyItem<T>* anyitem = static_cast<AnyItem<T>*>(item);
		return anyitem->get();
	}

	template<typename T>
	T& ref() {
		AnyItem<T>* anyitem = static_cast<AnyItem<T>*>(item);
		return anyitem->ref();
	}

	bool empty() const {
		return item == nullptr || item->empty();
	}

	Any operator=(const Any& x) {
		Any tmp(x);
		this->swap(tmp);
		return *this;
	}
 
	template<typename T>
	Any operator=(const AnyItem<T>& x) {
		Any tmp(x);
		this->swap(tmp);
		return *this;
	}
 
	template<typename T>
	Any operator=(const T& x) {
		Any tmp(x);
		this->swap(tmp);
		return *this;
	}

	const std::type_info& type() const {
		return item->type();
	}
private:
	void swap(Any& x) {
		using std::swap;
		swap(this->item, x.item);
	}
 
	const IAnyItem* getItem() const {
		return item;
	}
private:
	IAnyItem* item;
};
 
#endif

测试

int main() {
	string* ss = new string("yy");
	vector<Any> t;
	Any a(123);
	Any b(string("xxx"));
	Any c(ss);
	t.push_back(a);
	t.push_back(b);
	t.push_back(c);

	auto x = t[0].any_cast<int>();
	auto s = t[1].any_cast<string>();
	auto k = t[2].any_cast<string*>();


	cout << x << " " << s <<" "<< *k << endl;

	system("pause");
	return 0;
}

对于char*, const char* 类型, Any容器内部自动转为std::string。所以外部在使用时需要将其转为std::string类型;

如:char buf[100] = {'1','2'}; Any a(buf);  std::string str = a.any_cast<std::string>(); 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值