模板的类型萃取
分析类型萃取问题
功能:
类型萃取,在STL中用到的比较多,用于判断一个变量是否为POD(plain old data,平凡类型)类型。
简单来说可以用来判断出某个变量是内置类型还是自定义类型。
通过类型萃取,萃取到变量类型,对不同变量进行不同处理,可以提升程序效率。
应用场景:
例如实现顺序表,在对顺序表进行扩容时,利用类型萃取,重新开辟内存、拷贝对象。
拷贝对象时,分两种情况:1)内置类型,如int、char……;2)自定义类型,如Date类、SeqList类。
对于内置类型,可通过memcpy函数进行拷贝,此时进行的是浅拷贝。
而,对于自定义类型,大多数需要深拷贝的对象来说,必须调用赋值语句来赋值。
因此,在拷贝对象时,为不出错,通常用赋值语句来赋值。但缺点是效率较低。
通过类型萃取判断POD类或非POD类,对于POD类用浅拷贝,memcpy函数,对于非POD类用深拷贝,进行赋 值,这样就可以提高程序效率。
实现:
类型萃取,在技术层面,就是利用了模板的特化。
下面举例说明:
template<class T>
void SeqList::CheckCapacity()
{
_capacity=_capacity>0?_capacity*2:3;
T* tmp=new T[_capacity];
if(_a)
{
memecpy(tmp,_a,sizof(T)*_size);
delete[] _a;
}
_a=tmp;
}
代码中,当T为内置类型时,可以正常运行,但当T为自定义类型时会出错,原因是memcpy是浅拷贝,自定义类型中如果有指针,当扩容前存了指针ptr进去,使用CheckCapacity()扩容时,delete[] _a会清理释放ptr指向的内容,当使用memcpy函数进行浅拷贝后,扩容后的ptr为野指针,当程序执行结束时会调用析构函数,那么将会对同一块空间析构两次。
类型萃取的代码如下:
template<class T>
struct _TypeTraits
{
//POD——基本类型,指在C++中与C兼容的类型,可以按照C的方式处理。
typedef _FalseType IsPODType;
};
template<>
struct _TypeTraits<int>//特化
{
typedef _TrueType IsPODType;
};
template<class T>
T* TypeCopy(T* dst, const T* src, size_t n)
{
return _TypeCopy(dst, src, n, _TypeTraits<T>::IsPODType());
};
template<class T>
T* _TypeCopy(T* dst, const T* src, size_t n, _FalseType)
{
T* Dst = dst;
for (size_t i = 0; i<n; ++i)
{
dst[i] = src[i];
}
return Dst;
};
template<class T>
T* _TypeCopy(T* dst, const T* src, size_t n, _TrueType)
{
return (T*)memcpy(dst, src, n*sizeof(T));
};
测试代码如下:
void Test()
{
int a1[3] = { 1, 2, 3 };
int a2[3];
char s1[]="aabbcc";
char s2[7];
TypeCopy(a2, a1, 3);
TypeCopy(s2, s1, 7);
for (size_t i = 0; i<3; ++i)
{
cout << a2[i] << " ";
}
cout << endl;
for (size_t i = 0; i<7; ++i)
{
cout << s2[i] << " ";
}
cout << endl;
}
int main()
{
Test();
system("pause");
return 0;
}
运行结果:
分析图如下:
上一篇: CSS学习(1)
下一篇: 按值传递引用类型&按引用传递引用类型
推荐阅读
-
获得客户端使用操作系统类型的php代码
-
Thinkphp模板中使用自定义函数的方法_PHP
-
怎么从数据库中获取格式化的datetime类型值
-
thinkphp使用literal防止模板标签被解析的方法
-
Ci框架一般用于开发什么类型的项目比较合适??
-
四:redis的sets类型相关操作(有序和无序集合)
-
JavaEE基础day02 1.定义Java中的变量 四类八种 2.变量定义和使用的注意事项 3.数据类型的转换、强制数据类型转换4.算数运算符、比较运算符、逻辑运算符、赋值运算符、三元运算符
-
ecshop怎样套用新的模板,新的模板文件都是html的
-
Yii2的相关学习记录,后台模板和gii(三) - 漫游云巅
-
Linux创建FIFO文件类型的方法