当线性表这个数据结构用模板来完成时,若出现用户自定义类型(这里指的是会存在深浅拷贝的类型时如string),则这个模板的赋值运算符重载与拷贝构造就可能会出现BUG,这种BUG是源于对同一块地址进行了两次析构所导致的。为了解决这个问题,我们可以用类型萃取,当我们获取到的是不涉及深浅拷贝的线性表时,则我们调用普通的memcpy来完成复制,若涉及深浅拷贝,则我们用用户自定义类型已经重载过的赋值运算符进行赋值,其代码如下:
#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;
};
如有不足希望指正
转载于:https://blog.51cto.com/10743407/1752935