C++模板剖析:函数模板、类模板解析

本文深入探讨了C++中的模板和泛型编程,指出函数重载、公共基类和预处理程序的局限性,并引出泛型编程的概念。详细解释了函数模板和类模板的定义、作用、实例化过程,包括模板参数、类型推断、模板特化等关键点,并通过示例代码展示了模板在实际编程中的应用和注意事项。
摘要由CSDN通过智能技术生成

C++中关于模板&泛型编程问题:

 

问题引入:何编写一个通用加法函数?

 

(1)使用函数重载,针对每个所需相同行为的不同类型重新实现它

int Add(const int &_iLeft, const int&_iRight)

{

return (_iLeft +_iRight);

}

float Add(const float &_fLeft, constfloat &_fRight)

{

return (_fLeft +_fRight);

}

【缺点】

1、只要有新类型出现,就要重新添加对应函数。

2、除类型外,所有函数的函数体都相同,代码的复用率不高

3、如果函数只是返回值类型不同,函数重载不能解决

4、一个方法有问题,所有的方法都有问题,不好维护。

 

(2)使用公共基类,将通用的代码放在公共的基础类里面

 

【缺点】

1、借助公共基类来编写通用代码,将失去类型检查的优点;

2、对于以后实现的许多类,都必须继承自某个特定的基类,代码维护更加困难。

 

(3)使用特殊的预处理程序

#define ADD(a, b) ((a) + (b))

【缺点】

不是函数,不进行参数类型检测,安全性不高

 

综上所述的问题,我们需要引入泛型编程,即为需要的函数或者类编写一个模板,在实用的时候实例化即可。那么,什么是泛型编程?什么是模板?

 

一、   泛型编程

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

二、   函数模板

函数模板:代表了一个函数家族,该函数与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。

模板函数定义的格式:template<typename T1, teypename T2, ……….typename Tn>

函数返回值 函数名(参数列表)

{

       . . . . . .

}

 

Eg:

       template<typename T>

T Add( T left, T right )

{

       return left+right;

}

       template和typename 为关键字,T为模板形参的名字,可随意命名。

 

typename是用来定义模板参数关键字,也可以使用class。建议尽量使typename。

      

       实例化:模板是一个蓝图,它本身不是类或者函数,编译器用模板产生指定的类或者函数的特定类型版本,产生模板特定类型的过程称为函数模板实例化



注:模板被编译了两次:

① 实例化之前,检查模板代码本身,查看是否出现语法错误,如:遗漏分号

②在实例化期间,检查模板代码,查看是否所有的调用都有效,如:实例化类型不支持某些函数调用

 

实参推演:

从函数实参确定模板形参类型和值的过程称为模板实参推断,多个类型形参的实参必须完全匹配

类型形参转换:

一般不会转换实参以匹配已有的实例化,相反会产生新的实例。

编译器只会执行两种转换:

1、const转换:接收const引用或者const指针的函数可以分别用非const对象的引用或者指针来调用

 

2、数组或函数到指针的转换:如果模板形参不是引用类型,则对数组或函数类型的实参应用常规指针转换。数组实参将当做指向其第一个元素的指针,函数实参当做指向函数类型的指针。

 

Eg:

template<typename T>

void FunTest1(const T* t)

{

  cout<<"FunTest1();"<<*t<<endl;

}

template<typename T>

void FunTest2(const T& t)

{

   cout<<"FunTest2();"<<t<<endl;

}

template<typename T>

void FunTest3(T t1, T t2)

{

  cout<<"FunTest3()"<<endl;

}

 

int Add(int a, int b)

{

  return a+b;

}

int main()

{

  int A = 10;

  int* pA = &A;

  FunTest1(pA);

 

  int b = 20;

  int& pB = b;

  FunTest2(pB);

 

  int array1[10];

  int array2[20];

 

  FunTest3(array1, array2);

  FunTest3(Add,Add);

  system("pause");

  return 0;

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值