您的位置:首页 > 其它

Variant类,实现单链表原型中节点可存储任意类型

2013-11-12 09:14 267 查看
首先做一个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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: