C++之模板的超实用解析

一、模板的分类

模板可分为函数模板类模板


二、模板的使用顺序

函数包括声明和定义,声明在.h文件中,定义在.cpp文件中。函数模板也包括声明和定义,只不过它们都位于.h文件中。使用顺序是在.h文件中声明 -> 在.h文件中定义 -> 在.cpp文件中实例化并使用

类包括定义和实现,定义在.h文件中,实现在.cpp文件中。类模板也包括定义和实现,只不过它们都位于.h文件中。使用顺序是在.h文件中定义 -> 在.h文件中实现 -> 在.cpp文件中实例化并使用

注明:编译器将某一.cpp文件编译成.o文件的过程中,会忽略该.cpp文件中的模板,直到在该.cpp文件中发现了模板实例化,编译器才会对该模板进行编译。

也就是说:不进行实例化,模板写了也白写,因为编译器会直接忽略它。


三、模板的使用格式

3.1 函数模板的声明和定义格式

函数模板的声明和定义位于.h文件中,其格式如下所示:

//sample.h

//函数模板的声明
template <typename T> void swap(T& t1, T& t2);

//函数模板的定义
template <typename T> void swap(T& t1, T& t2)
{
    T temp;
    temp = t1;
    t1 = t2;
    t2 = temp;
}

3.2 函数模板的实例化格式

函数模板的实例化位于.cpp中,因为在.cpp中我们要使用模板了。

实例化分为隐式实例化显示模板实参显示实例化三种。为了方便记忆,我把这三种实例化方式与函数模板具体化一起记忆。

它们的格式复杂程度是按顺序依次递升的:隐式实例化->显示模板实参->显示实例化->具体化。其格式如下所示:

//main.cpp

#include <iostream.h>
#include "sample.h"

int main(int argc, char* argv[])
{
    int num1 = 1, num2 = 2;
    
    //隐式实例化:就像调用普通函数一样
    swap(num1, num2);

    //显示模板实参
    swap<int>(num1, num2);
    
    //显示实例化
    template void swap<int>(int& t1, int& t2);
    swap(num1, num2);

    cout<<"num1:"<<num1<<endl;
    cout<<"num2:"<<num2<<endl;

    return 0;
}

函数模板具体化应放在.h文件中,和函数模板的定义放在一块。

//sample.h

//函数模板具体化
template <> void swap<int>(int& t1, int& t2)
{
    //具体实现过程
    ...
    ...
}

咱家喜欢使用显示模板实参实例化函数模板。


3.3 类模板的定义和实现格式

类模板的定义和实现位于.h文件中,其格式如下所示:

//sample.h

#include <iostream>

//类模板的定义
template<typename T>
class Compare
{
public:
    Compare(T i,T j);

    T max(); 

    void ShowCPNumber();

    template<typename B>
    void Show(B b);

private:
    T x,y; 
};

//类模板的实现
//构造函数的类外定义
template<typename T>
Compare<T>::Compare(T i,T j)
{
    x = i;
    y = j;
}

//带类型参数的成员函数的类外定义
template<typename T>
T Compare<T>::max()
{
    return (x>y)?x:y;
}

//不带类型参数的成员函数的类外定义
template<typename T>
void Compare<T>::ShowCPNumber()
{
    cout<<"number1:"<< x <<endl;
    cout<<"number2:"<< y <<endl;
}

//模板成员函数的类外定义
template<typename T>
template<typename B>
void Compare<T>::Show(B b)
{
    cout<<"number3:"<< b <<endl;
}

从上面可以发现:类模板中的成员函数,可以在类模板外定义。此时,不论成员函数是否为构造函数,是否为模板函数,是否包含类型参数,C++都规定:

1)需要在成员函数定义之前进行模板声明;

2)在成员函数名前缀上"类名<类型参数>::";

3.4 类模板的实例化格式

类模板我一般使用显示模板实参实例化,其它实例化方法不是很清楚。不过,其实知道显示模板实参这一种实例化方法就够了。

类模板实例化格式如下所示:

//main.cpp

#include "sample.h"

int main(int argc, char* argv[])
{
    //显示模板实参
    Compare<int>com1(3,7);                       //用类模板定义对象com1,此时T被int替代 
    Compare<double>com2(12.34,56.78);            //用类模板定义对象com2,此时T被double替代 
    Compare<char>com3('a','x');                  //用类模板定义对象com3,此时T被char替代 

    cout<<"其中的最大值是:"<<com1.max()<<endl;   
    cout<<"其中的最大值是:"<<com2.max()<<endl;
    cout<<"其中的最大值是:"<<com3.max()<<endl;

    return  0;
}

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值