【代碼】模板動態線性表&類型萃取

    當線性表這個數據結構用模板來完成時,若出現用戶自定義類型(這裏指的是會存在深淺拷貝的類型時如string),則這個模板的賦值運算符重載與拷貝構造就可能會出現BUG,這種BUG是源於對同一塊地址進行了兩次析構所致使的。爲了解決這個問題,咱們能夠用類型萃取,當咱們獲取到的是不涉及深淺拷貝的線性表時,則咱們調用普通的memcpy來完成複製,若涉及深淺拷貝,則咱們用用戶自定義類型已經重載過的賦值運算符進行賦值,其代碼以下:
ios

    

#pragma once
#include<iostream>
#include<string>
struct __TrueType//定義類型是否爲須要在堆上開闢空間的類型
{
	bool Get()
	{
		return true;
	}
};

struct __FalseType
{
	bool Get()
	{
		return false;
	}
};

template <class _Tp>
struct TypeTraits
{
	typedef __FalseType   __IsPODType;
};

template <>
struct TypeTraits< bool>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< char>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned char >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< short>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned short >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< int>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned int >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< long>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned long >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< long long >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned long long>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< float>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< double>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< long double >
{
	typedef __TrueType     __IsPODType;
};

template <class _Tp>
struct TypeTraits< _Tp*>
{
	typedef __TrueType     __IsPODType;
};

template <class T>//線性表的模板
class SeqList
{
public:
	SeqList()
		:_size(0),
		_capacity(10),
		_array(new T[_capacity])
	{
		memset(_array,0,sizeof(T)*_capacity);
	}
	SeqList(const T &x)
		:_size(1),
		_capacity(10),
		_array(new T[_capacity])
	{
		_array[0] = x;
	}
	SeqList(const SeqList & x)
	{
		_array = new T[x._size];
		my_memcpy(_array, x._array, sizeof(T)*x._size);//重寫的內存複製函數
		_capacity = x._size;
		_size = _capacity;
	}
	void PushBack(const T & x)
	{
		_CheckCapacity();
		_array[_size++] = x;
	}
	SeqList & operator = (SeqList  l)
	{
		swap(_array, l._array);
		swap(_size, l._size);
		swap(_capacity, l._capacity);
		return *this;
	}

	~SeqList()
	{
		if (_array)
		{
			delete[] _array;
		}
	}
private:
	void _CheckCapacity()
	{
		if (_size >= _capacity)
		{
			_capacity *= 3;
			T * tmp = new T [_capacity];
			memcpy(tmp, _array, sizeof(T)*_capacity);
			delete[] _array;
			_array = tmp;
		}
	}
	void my_memcpy(T* dst, const T* src, size_t size)
	{
		if (TypeTraits <T>::__IsPODType().Get())//若爲不須要在堆上開闢空間的類型
		{
			memcpy(dst, src, size*sizeof (T));
		}
		else//須要在堆上開闢空間的類型
		{
			for (size_t i = 0; i < size; ++i)
			{
				dst[i] = src[i];
			}
		}
	}
	size_t _size;
	size_t _capacity;
	T *_array;
};

    若有不足但願指正
數據結構

相關文章
相關標籤/搜索