一、什么是类型萃取,它有什么作用
1. 类型萃取是实现不同类型数据面对同一函数实现不同的操作。
2. 增强代码的复用性和可维护性。
3. 它与类封装的区别是:并不用知道所调用的对象是什么类型,类型萃取是编译后知道类型,先实现;而类的封装则是先定义类型,后实现方法。
二、【POD类型萃取】
POD: plain old data 平凡类型(无关痛痒的类型)–基本类型
指在C++ 中与 C兼容的类型,可以按照 C 的方式处理。
通常数据的拷贝有两种,一种为浅拷贝(值拷贝),另一种为深拷贝。
浅拷贝:只是对指针的拷贝,拷贝后两个指针指向同一个内存空间。
深拷贝:不对指针进行拷贝,而对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
一般当遇到string类型的拷贝时,我们需要进行深拷贝,否则会导致同一块儿空间析构多次,造成程序崩溃或;者已经释放掉源操作数的空间,我们又解引用目的操作数的空间,由于是浅拷贝,这两个空间地址相同,对其释放后又解引用,程序依然会崩溃,会造成野指针问题。
## 这里我们举个例子 ##
//TypeTraits.h
struct __TrueType{};
struct __FalseType{};
template<class T>
struct __TypeTraits
{
typedef __FalseType IsPODType; // 内嵌重定义
};
template<>
struct __TypeTraits<int>
{
typedef __TrueType IsPODType;
};
template<>
struct __TypeTraits<unsigned int>
{
typedef __TrueType IsPODType;
};
template<>
struct __TypeTraits<char>
{
typedef __TrueType IsPODType;
};
template<>
struct __TypeTraits<double>
{
typedef __TrueType IsPODType;
};
//具体实现对一种引用memcpy浅拷贝
template<class T>
T* __TypeCopy(T* dst, const T* src, size_t n, __TrueType)
{
// int char...
cout<<"memcpy"<<endl;
return (T*)memcpy(dst, src, n*sizeof(T));
}
//对于像string类型的进行深拷贝
template<class T>
T* __TypeCopy(T* dst, const T* src, size_t n, __FalseType)
{
// string
cout<<"for+operator="<<endl;
for (size_t i = 0; i < n; ++i)
{
dst[i] = src[i]; // operator=
}
return dst;
}
//最终提供给用户的拷贝函数
template<class T>
T* TypeCopy(T* dst, const T* src, size_t n)
{
return __TypeCopy(dst, src, n, __TypeTraits<T>::IsPODType());
}
//Test.cpp
void TestCopy()
{
int a1[3] = {1, 2, 3};
int a2[3] = {0, 0, 0};
TypeCopy(a1, a2, 3);
string s1[3] = {"11", "22", "33"};
string s2[3] = {"0", "0", "0"};
TypeCopy(s1, s2, 3);
}
int main(void)
{
TestCopy();
return 0;
}
这里我们配图再进行说明整个调用过程
在VS2013上运行结果
可以清楚的看到两个虽然调用的是同一个拷贝函数,但是在底层确是用不同的方式实现的。
这就是简单的类型萃取。