当线性表这个数据结构用模板来完成时,若出现用户自定义类型(这里指的是会存在深浅拷贝的类型时如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; };
如有不足希望指正
本文出自 “pawnsir的IT之路” 博客,请务必保留此出处http://10743407.blog.51cto.com/10733407/1752935
原文:http://10743407.blog.51cto.com/10733407/1752935