首先做一个Variant类,其实在Boost库中有Variant类,但是还是自己实现一个功能比较简单的小规模的类。
当然如果想要一个存储任意类型的数据的类,肯定要用到指针,这个是第一点。比较难的点是任意数据类型的析构,在这里本来想用std::allocator来实现。现在自己写了一个简单的,废话不多说,上代码。
这个是我自己的variant类的实现(Variantjmy),my_variant.h头文件:
/*
realize the logic of variant,we could store any type
of value in the variant type
*/
#ifndef MY_VARIANT_H
#define MY_VARIANT_H
#include <iostream>
#include <string>
#include <memory>
class IAllocator
{
public:
virtual ~IAllocator() {};
virtual void construct(void* p) = 0;
virtual void destroy(void* p) = 0;
};
//IAllocator::~IAllocator(){}
template<typename T>
class myAllocator: public IAllocator
{
public:
void construct(void* p)
{
new (p)T(); //new T from the address of p
}
void destroy(void* p)
{
((T*)p)->~T();
}
};
class Variantjmy
{
private:
union u_value
{
int u_i;
double u_d;
float u_f;
char u_c;
};
//accept the normal type of data
u_value my_union;
//point to the abnormal type of data
void *m_pstr;
std::shared_ptr<IAllocator> m_alloc;
public:
Variantjmy():m_pstr(nullptr){}
~Variantjmy()
{
if (m_alloc.get() != nullptr)
{
m_alloc->destroy(m_pstr);
}
}
//setValue
template<typename T>
void setValue(const T inValue)
{
m_alloc.reset(new myAllocator<T>());
void* pmem = malloc(sizeof(T));
m_alloc->construct(pmem);
m_pstr = pmem;
*(T*)m_pstr = inValue;
}
//setValue's template specialize
template<>
void setValue(const int inValue)
{
my_union.u_i = inValue;
}
template<>
void setValue(const double inValue)
{
my_union.u_d = inValue;
}
template<>
void setValue(const float inValue)
{
my_union.u_f = inValue;
}
template<>
void setValue(const char inValue)
{
my_union.u_c = inValue;
}
//getValue function
template<typename T>
T getValue()
{
return *(T*)m_pstr;
}
template<>
int getValue<int>()
{
return my_union.u_i;
}
template<>
double getValue<double>()
{
return my_union.u_d;
}
template<>
float getValue<float>()
{
return my_union.u_f;
}
template<>
char getValue<char>()
{
return my_union.u_c;
}
};
#endif // MY_VARIANT_H
上面的代码就实现了存储任意类型的类,下面当然是用单链表来包一下数据,但是里面的函数我没有多写,只是简单的插入,删除。如果大家有兴趣可以发掘更多的功能。
代码variant_list.h
/*
realize the single-list and the node of the
list is a vector that fulled with variant
type value
*/
#ifndef VARIANTLIST_H_
#define VARIANTLIST_H_
#include <vector>
#include "my_variant.h"
class Variantlist
{
private:
struct LNode
{
Variantjmy value;
LNode* next;
};
LNode* header;
public:
Variantlist():header(nullptr){}
~Variantlist()
{
while (header != nullptr)
{
LNode* tempNode = header->next;
delete header;
header = tempNode;
}
}
//get the header
LNode* getheader()
{
return header;
}
//insert one kind of type value
template<typename T>
void insertNode(T data);
//deleteNode
bool deleteNode(LNode* delNode);
};
template<typename T>
void Variantlist::insertNode(T data)
{
Variantjmy tempvt;
tempvt.setValue(data);
LNode* newNode = new LNode;
newNode->value = tempvt;
if (header == nullptr)
{
header = newNode;
}
else
{
LNode* tempNode = header;
while (tempNode->next != nullptr)
{
tempNode = tempNode->next;
}
tempNode->next = newNode;
}
newNode->next = nullptr;
}
bool Variantlist::deleteNode(LNode* delNode)
{
if (header == nullptr || delNode == nullptr)
{
return false;
}
Variantjmy tempvt;
LNode* tempNode = new LNode;
tempNode = header;
while (tempNode->next != delNode)
{
tempNode = tempNode->next;
if (delNode->next == nullptr)
{
tempNode->next =nullptr;
}
else
{
tempNode->next = delNode->next;
}
delete delNode;
return true;
}
return false;
}
#endif