模板的类型萃取
2017-11-22 23:17
288 查看
分析类型萃取问题
功能:
类型萃取,在STL中用到的比较多,用于判断一个变量是否为POD(plain old data,平凡类型)类型。
简单来说可以用来判断出某个变量是内置类型还是自定义类型。
通过类型萃取,萃取到变量类型,对不同变量进行不同处理,可以提升程序效率。
应用场景:
例如实现顺序表,在对顺序表进行扩容时,利用类型萃取,重新开辟内存、拷贝对象。
拷贝对象时,分两种情况:1)内置类型,如int、char……;2)自定义类型,如Date类、SeqList类。
对于内置类型,可通过memcpy函数进行拷贝,此时进行的是浅拷贝。
而,对于自定义类型,大多数需要深拷贝的对象来说,必须调用赋值语句来赋值。
因此,在拷贝对象时,为不出错,通常用赋值语句来赋值。但缺点是效率较低。
通过类型萃取判断POD类或非POD类,对于POD类用浅拷贝,memcpy函数,对于非POD类用深拷贝,进行赋 值,这样就可以提高程序效率。
实现:
类型萃取,在技术层面,就是利用了模板的特化。
下面举例说明:
代码中,当T为内置类型时,可以正常运行,但当T为自定义类型时会出错,原因是memcpy是浅拷贝,自定义类型中如果有指针,当扩容前存了指针ptr进去,使用CheckCapacity()扩容时,delete[] _a会清理释放ptr指向的内容,当使用memcpy函数进行浅拷贝后,扩容后的ptr为野指针,当程序执行结束时会调用析构函数,那么将会对同一块空间析构两次。
类型萃取的代码如下:
测试代码如下:
运行结果:
分析图如下:
功能:
类型萃取,在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; }
运行结果:
分析图如下:
相关文章推荐
- C++ 模板 之 类型萃取 与 容器适配器
- 模板的类型萃取
- 模板的类型萃取
- c++ 类型萃取(模板类型 运用)
- C++ 模板类型萃取技术
- 小结 | C++模板的类型萃取
- C++ 模板 之 类型萃取 与 容器适配器
- 模板的类型萃取
- 【代码】模板实现动态线性表(无类型萃取)
- c++:模板的类型萃取
- C++ 模板类型萃取技术 traits
- 模板的使用:Promotion Traits( 类型提升之特征萃取)
- 模板的类型萃取
- c++:模板的类型萃取
- 【C++】模板简述(五):类型萃取
- 通过模板的特化实现 简单的类型萃取 实现memcppy时候对于特殊类型如string类的拷贝。
- C++ 模板类型萃取技术 第一部分 为什么要有萃取技术
- 模板的类型萃取
- 模板的类型萃取
- 【代码】模板实现动态线性表(无类型萃取)