泛型编程
所谓的泛型编程,即参数类型化,C++的泛型采用模板来实现。
ps:有可能遇到VC6++能编译通过的模板,可能VC++2013通不过
编译器不一定支持所有标准文档。写模板尽量精炼
1.先看下重载的函数:
int Add(int a, int b)
{
return a + b;
}
float Add(float a, float b)
{
return a + b;
}
/*同样功能的函数,在使用重载语法的时候,需要重复写功能一样的代码*/
2.函数模板
2.1 语法及基本用法概述
template<typename 模板参数列表> 返回值 函数名(参数列表)
/*模板参数表示在类或函数定义中用到的类型或值,在使用模板时候(实例化的时候),我们(显式或隐式)指定模板实参,将其绑定到模板参数*/
//例1
template<typename TYPE> TYPE Add(TYPE a, TYPE b)
{
return a + b;
}
//特例化
template<> char* Add(char* a, char* b)
{
strcat(a, b);
return a;
}
//声明和实现做在一起,或者声明实现分开,但必须在同一个.h文件中
/*有点类似于宏,不单独参与编译,必须在实例化的时候才参与编译(检查代码)*/
2.2函数模板实例化
class A
{
public:
A operator+ (A& obj)//类支持泛型,需要重载运算符
{
return *this;
}
}
int main()
{
/*显示实例化模板:1.首次调用实例化代码。2.检查语法*/
int n = Add<int>(1,2);//显式实例化
A obj1,obj2;
Add(obj1,obj2);//隐式转换成类类型
char szBuf[30];
Add(szBuf, "hello!");//调用特例化模板
/*编译链接完,在可执行文件中没有模板的信息,本质上模板的作用匹配模板生成代码*/
/*在逆向中,没办法还原模板信息,也就是说不知道是代码是直接写还是通过模板实例化的*/
}
3.类模板
3.1 类模板语法及基本用法概述
template<class 模板参数表> class 类名{ // 类定义...... }
/*其中,template 是声明类模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个,可以是类型参数 ,也可以是非类型参数。类型参数由关键字class或typename及其后面的标识符构成。非类型参数由一个普通参数构成,代表模板定义中的一个常量。*/
template<class type,int width> class Graphics{ }
/*type为类型参数,width为非类型参数*/
//例2
template<class T>
class A
{
public:
A()
{
}
~A()
{
}
private:
static T m_nCount;
};
template<class T>
T A<T>::m_nCount = 0;//相应静态数据成员初始化
//例2-特例化
template<>
class A<int>
{
public:
A()
{
}
~A()
{
}
private:
static int m_nCount;//静态数据成员特例化
};
int A<int>::m_nCount = 1;//相应静态数据成员初始化
3.2 类模板参数可以有缺省实参,给参数提供缺省实参的顺序是先右后左。
template <class T, int size = 1024>
class Point;
template <class T=double, int size >
class Point;
智能指针类模板设计
//引用计数类 RefCount.h
class RefCount
{
public:
RefCount();
virtual ~RefCount();
public:
int AddRef();
int Release();
static int m_nCount;
};
//引用计数类 RefCount.cpp
RefCount::RefCount()
{
}
RefCount::~RefCount()
{
}
int RefCount::AddRef()
{
return ++m_nCount;
}
int RefCount::Release()
{
return --m_nCount;
}
int RefCount::m_nCount = 0;
智能指针类模板
template<class TYPE>
class CSmartPtr
{
public:
CSmartPtr();
CSmartPtr(TYPE *pObject);
CSmartPtr(const CSmartPtr& obj);
~CSmartPtr();
CSmartPtr& operator= (const CSmartPtr& obj);
TYPE* operator-> ();
TYPE** operator& ();
TYPE& operator* ();
operator TYPE* ();
TYPE* operator++ (int);
TYPE* operator++ ();
TYPE* operator-- (int);
TYPE* operator-- ();
private:
TYPE* m_pObject;
};
//类模板的声明和实现分开,但必须在同一个.h文件中
template<class TYPE>
CSmartPtr<TYPE>::CSmartPtr()
{
m_pObject = NULL;
}
template<class TYPE>
CSmartPtr<TYPE>::CSmartPtr(TYPE *pObject)
{
m_pObject = pObject;
m_pObject->AddRef();
}
template<class TYPE>
CSmartPtr<TYPE>::CSmartPtr(const CSmartPtr& obj)
{
m_pObject = obj.m_pObject;
m_pObject->AddRef();
}
template<class TYPE>
CSmartPtr<TYPE>::~CSmartPtr()
{
if (m_pObject->Release() == 0)
{
delete m_pObject;
m_pObject = NULL;
}
}
template<class TYPE>
CSmartPtr& CSmartPtr<TYPE>::operator= (const CSmartPtr& obj)
{
if (this == &obj)
return *this;
//释放原来的引用
if (m_pObject != NULL)
m_pObject->Release();
m_pObject = obj.m_pObject;
m_pObject->AddRef();
return *this;
}
template<class TYPE>
CSmartPtr<TYPE>::TYPE* operator-> ()
{
return m_pObject;
}
template<class TYPE>
CSmartPtr<TYPE>:: TYPE** operator& ()
{
return &m_pObject;
}
template<class TYPE>
CSmartPtr<TYPE>::TYPE& operator* ()
{
return *m_pObject;
}
template<class TYPE>
CSmartPtr<TYPE>::operator TYPE* ()
{
return m_pObject;
}
template<class TYPE>
CSmartPtr<TYPE>::TYPE* operator++ (int)
{
return m_pObject++;
}
template<class TYPE>
CSmartPtr<TYPE>::TYPE* operator++ ()
{
return ++m_pObject;
}
template<class TYPE>
CSmartPtr<TYPE>::TYPE* operator-- (int)
{
return m_pObject--;
}
template<class TYPE>
CSmartPtr<TYPE>::TYPE* operator-- ()
{
return --m_pObject;
}
ps:模板跟宏不一样,模板可以调试,宏不能调试
类模板必须显示实例化
//智能指针类模板化后可以重复使用
Smartptr<A> ptr1(new A());
Smartptr<B> ptr2(new B());