C++模版简介(初阶)

泛型编程

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。
模版是泛型编程的基础

模版

模版分为函数模版和类模版

函数模版

template:模版

函数模版的格式
template < class T1,class T2,class T3,…,class Tn>
返回值类型 函数名(参数列表) {}
定义模版参数的关键字可以用class,也可以用template

//template <typename T>
template <class T>
void swap(T& a,T& b)
{
   T tmp = a;
   a = b;
   b = tmp;
}
int main()
{
  int i = 1,j = 2;
  double m = 1.1,n = 2.2;
  swap(i,j);
  swap(m,n);
  //用的是同一个模版,但是编译器生成的是不同的函数
  
  return 0;
}

用模版的好处:C语言规定函数不能同名,要写两个不同名的函数,C++有函数重载,可以同名,但是也要写两个参数不同的函数,用函数模版可以提高效率不用写两个函数了

1.函数模版的三种写法:

template <class T1,class T2>
template <class T1,typename T2>//关键字混用也可以
template <typename T1,typename T2>

2.一个模版参数只能接收相同的类型

template <class T>
//只能传相同的类型,只能接收一种类型
template <class T1,class T2>
//可以接收不同的类型,可以传相同,也可以传不同类型

3.推导实例化和显示实例化
模版实例化:用函数模版生成对应的函数,跟用类名生成对应的对象一样(用类名实例化对象)

  • 推导实例化
1.推导实例化
template <class T>
void swap(T& a,T& b)
{
   T tmp = a;
   a = b;
   b = tmp;
}
int main()
{
  int i = 1,j = 2;
  double m = 1.1,n = 2.2;
  swap(i,j);//推导i和j是int类型
  swap(m,n);//推导m和n是double类型
 
  return 0;
  }
2.强制类型转换可以解决类型不明确的问题
int a1 = 0;
double d1 = 0;
cout << Add(a1,(int)d1) << endl;
cout << Add((double)a1,d1) << endl;
3.显示实例化
cout << Add<int>(a1,d1) << endl;
cout << Add<double>(a1,d1) << endl;

有时只能用显示实例化,不能用推导实例化

template <class T>
T* func1(int n)
{
   return new T[n];
}
//不在参数位置写T,不能推导出T类型
int main()
{
   func1(10); (x)
   double* p1 = func1<double>(10); (v)
   
   return 0;
}

如果有实际的函数存在和模版同时也存在,就走函数,因为编译器追求高效,不用推导实例化

类模版

类模版的定义格式

template <class T1,class T2,class T3...,class Tn>
class
{
   //类内成员定义
};

在类内声明,在类外初始化,要单独声明模版参数

template<class T>
class Stack
{ 
  void Push(const T& x);//声明
};

//初始化
template<class T>
void Stack<T>::Push(const T& x)
{
if (_size == _capacity)
{
		T* tmp = new T[_capacity * 2];
		memcpy(tmp, _array, sizeof(T) * _size);
		delete[] _array;

		_array = tmp;
		_capacity *= 2;
	}

	_array[_size++] = x;
}

模版使用和定义不分离在两个文件中(.h和.cpp),会造成链接错误
不看模版类型是否匹配,要看实例化后的函数类型是否匹配

C++中没有realloc,只能这样扩容

void Push(const T& x)
{
  if(_size == _capacity)
  {
    T* tmp = new T[_capacity*2];//扩2倍
    memcpy(tmp,_array,sizeof(T)*_size);
    //把数据拷贝到tmp中
    delete[] _array;
    //销毁原空间
    
    _array = tmp;//给新空间地址
    _capacity *= 2;//空间扩2倍
  }
  _array[_size++] = x;
  //插入数据x
}

类模版都是显示实例化

不同的类型
Stack<int> st1;//int
Stack<double> st2;//double

用的同一个模版,调用不同的类,编译器生成了两个不同的类,类模版的参数类型不同(int,double)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值