一.类模板的特化
类模板可以定义多个类型参数
template<typename T1,typename T2>
class Test
{
public:
void test(T1 a,T2 b)
{
cout<<a+b<<endl;
}
};
类模板可以被局部特化
--- 可以指定类模板的特定实现,并要求某些类型参数仍然的用户指定
template<typename T1,typename T2>
class Test
{
public:
void add(T1 a,T2 b)
{
cout<<"void add(T1 a,T2 b)"<<endl;
cout<<a+b<<endl;
}
};
/*
template<typename T>
class Test<T,T>
{
public:
void add(T a,T b)
{
cout<<"void add(T a,T b)"<<endl;
cout<<static_cast<T>(a,b)<<endl;
}
};
*/
template<typename T>
class Test<T,int>
{
public:
void add(T a,int b)
{
cout<<"void add(T a,int b)"<<endl;
cout<<a+b<<endl;
}
};
template<typename T1,typename T2>
class Test<T1*,T2*>
{
public:
void add(T1* a,T2* b)
{
cout<<"void add(T1* a,T2* b)"<<endl;
}
};
int main()
{
int i=0;
int j=0;
Test<double,int> t;// <T,int>
Test<long,long> ti;// <T,T>
Test<float,int> tt;// <T,int>
Test<int*,int*> tp;
t.add(10.0023,10);
ti.add(2,3);
tt.add(4,5);
tp.add(&i,&i);
return 0;
}
类特化的意义:
------- 特化和重新定义新类看上去没有本质区别,但是如果定义新的类,那么将变成一个类模板和一个新类,使用的时候就需要考虑使用类模板还是使用新的类。
------- 而特化可以统一的方式使用类模板和特化类,编译器自动优先选择特化类。
二. 非类型模板参数
函数模板和类模板的模板参数可以是普通数值
template <typename T,int N>
void func()
{
T array[N] ={0};
for(int i=0;i<N;++i)
{
array[i] =i+1;
cout<<array[i]<<" ";
}
cout<<endl;
}
int main()
{
func<int,5>();
func<float,10>();
return 0;
}
非类型模板参数与特化的实例:
template<int N>
class Sum
{
public:
static const int VALUE=Sum<N-1>::VALUE+N;
};
template<>
class Sum<1>
{
public:
static const int VALUE=1;
};
int main()
{
cout<<Sum<10>::VALUE<<endl;
cout<<Sum<100>::VALUE<<endl;
return 0;
}
非类型模板参数的限制
*: 变量不能作为模板参数
int a=10;
cout<<Sum<a>::VALUE<<endl; // 错误
*: 浮点数和类对象不能作为模板参数
*: 全局指针不能作为模板参数
说明: 编译器的推导过程是在编译器编译阶段完成的,因此,编译器的推导必须依赖特化类,否则推导过程无法结束。
三. 智能指针
工程中的智能指针是一个类模板
--- 通过构造函数接管申请堆内存
--- 通过析构函数确保堆内存被及时释放
--- 通过重载指针运算符 * 和 -> 模拟指针的行为
template <typename T>
class SmartPointer
{
protected:
T* _pointer;
public:
SmartPointer(const T* pointer);
~SmartPointer();
T* operator->();
T& operator*();
};
template<typename T>
SmartPointer<T>::SmartPointer(const T* pointer)
{
_pointer = const_cast<T*>(pointer);
}
template<typename T>
SmartPointer<T>::~SmartPointer()
{
delete _pointer;
}
template<typename T>
T* SmartPointer<T>::operator->()
{
return _pointer;
}
template<typename T>
T& SmartPointer<T>::operator*()
{
return *_pointer;
}
class Test
{
public:
int i;
void print()
{
cout<<"void print()\n"<<i<<endl;
}
};
int main()
{
SmartPointer<int> pi=new int(5);
SmartPointer<Test> pt=new Test;
cout<<*pi<<endl;
pt->i = 20;
pt->print();
return 0;
}
小结:
(1)类模板中可以有一个或者多个未指定的泛指类型
(2) 特化类可以统一的方式使用类模板和新定义的类
(3) 特化类总是被编译器优先选择使用
(4) 模板的参数可以是普通数值
(5) 智能转指针可以避免内存相关的问题