类型萃取是实现不同类型数据面对同一函数实现不同的操作,它与类封装的区别是并不用知道所调用的对象是什么类型,类型萃取是编译后知道类型,先实现而类的封装则是先定义类型,后实现方法。

类型分为基本类型(POD),和自定义类型

在这里用模板的特化实现其编程思想

memcpy为例,当拷贝的是基本类型(POD)时,只用拷贝所传递指针上的数据,如果是string类型,则需要在堆上开辟空间,所传递的指针如果被直接复制,则有可能(vs下的string类型的实现原理是若字符串不长则以数组保存,若字符串过长,则通过指针在堆上开辟空间进行保存)出现同一地址,析构两次出现错误。

程序

#include<iostream>

using namespace std;

#include<string>


struct __TrueType

{

static bool Get()

{

return true;

}

};


struct __FalseType

{

static bool Get()

{

return false;

}

};


template <class T>

struct TypeTraits//traits为特性

{

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<class T>

void _Memcpy(T& dest, const T& src, size_t size, __TrueType)    //基本类型

{

cout << "IsPOD::" << typeid(T).name() << endl;

memcpy(dest, src, sizeof(T)*size);

}


template<class T>

void _Memcpy(T& dest, const T& src, size_t size, __FalseType)

{

cout << "IsNotPOD::" << typeid(T).name() << endl;

for (int i = 0; i < size; i++)

{

dest[i] = src[i];

}

}


template<class T>

class SeqList

{

public:

SeqList()

:_size(0)

, _capacity(0)

, _array(NULL)

{}


SeqList<T>(const SeqList<T>& s)

{

_array = new T[s._size];

if (TypeTraits <T>::__IsPODType().Get())

{

_Memcpy(_array, s._array, s._size, TypeTraits<T>::__IsPODType());

}

else

{

_Memcpy(_array, s._array, s._size, TypeTraits<T>::__IsPODType());

}

swap(_size, s._size);

swap(_capacity, s._capacity);

}


SeqList<T>& operator= (SeqList<T> s)

{

swap(_array, s._array);

swap(_size, s._size);

swap(_capacity, s._capacity);

}


~SeqList()

{

if (_array)

{

delete[] _array;

_array = NULL;

}

}


void _CheckCapacity(size_t n)

{

if (n > _capacity)

{

_capacity = 2 * _capacity + 3;

T* tmp = new T[_capacity];

if (_array != NULL)

{

if (TypeTraits <T>::__IsPODType().Get())

{

_Memcpy(tmp, _array, _size, TypeTraits <T>::__IsPODType());

}

else

{

_Memcpy(tmp, _array, _size, TypeTraits <T>::__IsPODType());

}

}

delete[] _array;

_array = NULL;

_array = tmp;

}

}


void PushBack(const T& x);//尾插

void PopBack();//尾出

void PrintSeqList();//打印链表


private:

size_t _size;

size_t _capacity;

T* _array;

};



template<class T>

void SeqList<T>::PushBack(const T& x)

{

_CheckCapacity(_size + 1);

_array[_size++] = x;

}


template<class T>

void SeqList<T>::PopBack()

{

if (_size == 0)

{

return;

}

else

{

--_size;

}

}


template<class T>

void SeqList<T>::PrintSeqList()

{

for (int i = 0; i < _size; i++)

{

cout << _array[i] << "  ";

}

cout << endl;

}



//int的测试函数

//void Test()

//{

//    SeqList<int> s1;

//    s1.PushBack(1);

//    s1.PushBack(2);

//    s1.PushBack(3);

//    s1.PushBack(4);

//    s1.PushBack(5);

//    s1.PrintSeqList();

//    s1.PrintSeqList();

//}


//string的测试函数

void Test()

{

SeqList<string> s2;

s2.PushBack("Hello");

s2.PushBack("yaoyao! ");

s2.PrintSeqList();

s2.PrintSeqList();

}


int main()

{

Test();

system("pause");

return 0;

}

运行结果:

Hello  yaoyao!

Hello  yaoyao!

请按任意键继续. . .