C++模板

 模板的基本概念:

1.模板(template)是用来实现静态多态的,c++语言中常用的一种高级泛型编程技术。

2.实现代码的可重用行(将类型定义成参数)。

3.在类和函数的基础上提供的更高一层的抽象(分为函数模板和类模板)。

函数模板格式:

 //模板函数
template<typename T>  //函数模板
T func(T a)  
{
     //函数体
}

类模板格式:

 //模板类
template<typename T>   //类模板
class  demo 
{
public:
        demo(T a){};
}
class test{};//普通类

注意:

1.模板只会和它的下一句相结合,类似,模板函数同样如此

2.typename可更改为class,但是不建议,class是已有定义的类的关键字,在c++11已取消此种用法

模板与宏的区别:

1.宏是编译时替换(没有类型检测)。

2.模板是编译时生成(对T类或类型T的函数实例化(编译,非运行时)时进行拷贝生成相应的代码;检查语法错误;检查调用错误)。

 类模板的函数定义方式:

注意:类模版中的所有成员函数定义写在.h文件中,模板的声明和实现不可分离在两个文件。

 类模板的成员函数实现方式:

其一:

template<typename T>
class Array
{
public:
         Array(){//...}
         ~Array(){//...}
         void Apprend(const T value){//...}
}

其二:

//同文件
template<typename T>
Array<T>::~Array(){//...}
template<typename T>
void Array<T>::Append(const T value){//...}

类模板的使用:

1.模板定义时可以有多个模板参数

例:

template<typename T1,typename T2>//可以支持多个
class Demo
{
public:
         Demo(T2 in){};
private:
         T1 tdemo;
         T2 t2demo;
}
int main()
{
          Demo <int ,float> demo(float(1.0002));
}

2.模板定义时的模板参数可以支持实际类型

例:

template<typename T1,int size = 10>  //size是一个模板参数
class Demo
{
public:
        Demo()
        {
                size_=size
        };
private:
         T1 tdemo;
         int size_;
}

3.模板参数还可以是在它前定义的模板类型推导的值

例:

template<typename T, T temp>//可以支持多个
class Demo
{
public:
        Demo()
        {
            tdemo = temp;
        };
private:
         T tdemo;
}
int main()
{
          Demo <int ,10> demo;
}

4.模板参数必须是一个常量

例:

template<typename T, T temp>//可以支持多个
class Demo
{
public:
        Demo()
        {
            tdemo = temp;
        };
private:
         T tdemo;
}
int main()
{
          Demo <int ,10> demo;
          int num=10;
          const int len=10;
          //Demo<int,num>demo1;//程序报错;模板是在编译时实例化,函数类型不能是变量
          Demo<int,len>demo2;//函数类型常量,指针与引用为运行时才确定的类型,因此也不可用在此。
}

5.模板类是可以继承的

例:

template<typename T>
class Array{};
template<typename T>
class Statck:public Array<T>{};
class Vector:public Array<int>{};

注意:

1.类模板的参数类型是无法自动推导的,和函数模板不同,因此使用类模板时必须显示指定该类型

2.普通类可以继承模板类的一个指定类型,推荐用法是模板类继承模板类

6.成员模板

例:

template<template T>
class MyType
{
    public:
            template<typename X>
            void Assign(X other);//采用声明和实现分离的方式
}
class MyDemo
{
    public:
            template<typename T>
            const T& GetVal(const T& val);//采用声明和实现分离的方式
}
template<typename T>
template<typename X>
void MyType<T>::Assign(X other){}
template<typename T>
const T& MyDemo::GetVal(const T& val){}

函数模板的使用:

template<typename T>
void Swoap(T& lhs, T &rhs)
{
         T temp =lhs;
          lhs=rhs;
          rhs=temp;
}
int main()
{
         int lhs=10;
         double rhs = 20;
         Swoap(lhs,rhs);
}

模板函数的重载:

重载条件:

1.模板参数列表不同

2.函数参数列表不同

template<typename T>
void Swoap(T& lhs, T &rhs)
{
        T temp =lhs;
        lhs=rhs;
        rhs=temp;
}
template<typename T1, typename T2>//模板参数列表不同;函数参数列表不同
void Swoap(T1& lhs, T2 &rhs)
{
        T temp =lhs;
        lhs=rhs;
        rhs=temp;
}
int main()
{
     {
           int lhs=10,rhs=20;
           Swoap(lhs,rhs);//函数模板会生成Swoap<int>
     }
     {
          double lhs=10.03,rhs=20;.89
          Swoap(lhs,rhs);//函数模板会生成Swoap<double>
     }

}

注意:

1.若是程序中有匹配的函数,则函数模板不会生成新的函数

2.模板函数可与普通函数可构成重载

3. 模板参数列表中的类型元素如若不在函数参数列表中使用,则该类型无法自动推导,因此在调用时必须指明该类型

4.模板函数的重载是不能提升转换的(如下例)

#include<iostream>
using namespace std;
template<typename T>
const T GetMax(T lhs, T rhs)
{
	return lhs > rhs ? lhs : rhs;
}
template<typename T>
const T GetMax(double lhs, double rhs)
{
	return lhs > rhs ? lhs : rhs;
}
int main()
{
	GetMax(1, 2);
	GetMax('a', 'b');
	//GetMax('a',1);  //程序报错,模板函数的重载不存在提升转换
	GetMax<int>('a', 1);
	GetMax<double>(1.002, 2.001);//调用时必须指明该类型
	return 0;
}

纯手打 如有错 请指教!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值