模板分3大类:类模板,函数模板和成员模板
。成员模板是指类的成员函数是一个模板函数。其中类可以是一个普通的 类或者是一个模板类。
普通类的成员模板
- 一个简单的例子如下:
#include <iostream>
#include <memory>
using namespace std;
//Function-like class
class Debugdelete
{
public:
//重载(),是一个fuction-like class
template <typename T>
void operator()(T* p) const
{
cout << "deleting unique_ptr " << endl;
delete p;
}
};
int main()
{
int *p = new int;
Debugdelete d;
//使用对象调用operator()(int *)
d(p);//delete p
string *s = new string;
//使用临时的对象调用operator()(string *)。其中,Debugdelete()会生成临时的对象
Debugdelete()(s);//delete s
system("pause");
return 0;
}
上面的类Debugdelete
是一个普通的类,它重载了小括号(),是一个function-like class。它的作用是delete模板T类型的内存
。
就像函数模板一样,使用成员模板同样不需要用<>说明类型。
- 将
Debugdelete
用作unique_ptr
的删除器
在上述例子的main函数中定义一个unique_ptr对象,并用Debugdelete作为析构时的删除器。如下
unique_ptr<int, Debugdelete> u(new int(5), Debugdelete());
这样,当释放new int(5)
内存时,就调用operator()(T *)。其中T的类型在构造unique_ptr时指明,这里T就是int。
模板类的成员模板
下面在Blob.h中定于一个Blob模板类,其中Blob的构造函数又是一个成员模板。
#ifndef _BLOB_H
#define _BLOB_H
template<typename T>
class Blob
{
template<typename It>
Blob(It b, It e);
};
template<typename T>
template<typename It>
Blob<T>::Blob(It b, It e)
{
}
#endif
注意以下两点:
必须为类模板和成员模板都写上template<>,并且类模板的在前
Blob<T>中的<T>是不能省略的,因为它是一个模板类,带上模板才是一个完整的类
下面给出一个侯捷老师对STL中智能指针中成员模板说明的例子:
- 第1块是STL库中shard_ptr的一个构造函数,使用的就是成员模板。
- 第2块是我们自己定义的类
- 第3块是main中的测试
说明如下:
第3块中的第1句不用多说,就是父类指针指向子类。
现在我们使用智能指针,肯定也要实现相同的功能,所以使用时,类模板用Base1,构造函数用Derived1。