當線性表這個數據結構用模板來完成時,若出現用戶自定義類型(這裏指的是會存在深淺拷貝的類型時如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; };
若有不足但願指正
數據結構