15-类模板-(下)

一.类模板的特化

    类模板可以定义多个类型参数

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) 智能转指针可以避免内存相关的问题


  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值