模板 泛型编程

模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。C++泛型编程和面向对象是两个分离的编程思维方式,完全可以独立学习。泛型编程经典实践是标准库STL,深入研读和编写STL库文件能够较好提高编程能力。当然模板的使用必然会导致代码的膨胀,但是这种膨胀对于代码简洁性是非常有益的,其产生的多余内存也是可以接受的。

模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector <int>vector <string>。模板实际使用过程中分为类模板、函数模板和成员模板三中类型,下面一一对这三种类型模板概念进行说明。

1. 模板概念

在C++语言一开始为出现泛型编程概念,使用class作为模板的关键字,出现模板以后引入了typename。typename出现以后自定义类型内部的嵌套类型可以正常使用,同时也消除了类中同一个标识符可能导致的二义性。

1.1. 类模板

一些类主要用于存储和组织数据元素,类中的数据元素是与具体类型没有任何关系的,例如数组类、链表、queue等。C++将模板的思想应用于类,使得类实现不关注数据元素的具体类型,而只关注所需要的实现的功能。typename 是占位符类型名称,可以在类被实例化的时候进行指定,类型定义内部使用逗号分隔的列表来定义多个泛型数据类型。

template <typename type> class class-name {
...
}

template <typename type> m_var_type class-name::member = val;
template <typename type>
type class-name::func_member(...)
{}

类模板在工程中应用时,(1)必须在头文件中定义;(2)类模板不能分开实现在不同的文件中;(3)类模板外部定义的成员函数需要加上模板<>声明。

单例模板事例:单例模式 C++_生活需要深度-CSDN博客

1.2. 函数模板

实际代码开发过程中对于重复出现的代码我们可以使用宏实现,也可以使用函数实现。但是这两种方式都有一定的限制。对于宏代码,可以很好的实现代码复用,使用所有类型,但是编译器不知道宏的存在,没有办法进行参数检查。对于函数,通过函数调用编译器可以进行类型检查,但是无法实现代码复用。C++函数泛型编程可以很好结合如上两者的优点。

template <typename type> ret-type func-name(parameter list)
{
...
}

函数模板重载实例

1.3. 成员模板

template <typename T>
struct xxx
{
public:
  template <typename U>
  xxx(const U& a) {
    .......
  }
  typedef T first_type;
  T value;
};

成员模板 智能指针:智能指针原理与使用 C++_生活需要深度-CSDN博客

2. 模板编译与耦合

2.1. 模板编译流程

编译器对于模板的处理方式是相同的,通过两次编译完成才能生成最终可执行文件。在预编译处理阶段通过具体类型推到出不同的类,在声明的地方对类模板代码本身进行编译,在使用的地方对参数替换后的代码进行编译。

2.2. 模板模板参数

在实际开发过程中可能出现模板套用模板的概念,也就是模板中包含了另外一个模板。

2.3. 多参数模板

函数模板可以定义任意多个不同的类型参数,和单参数相比较这里无法自动推导返回值类型,需要从左到右部分指定参数类型,指定的开始位置必定是函数的返回值参数。

#include <iostream>
#include <string>

using namespace std;

template
< typename T1, typename T2, typename T3 >
T1 Add(T2 a, T3 b)
{
    return static_cast<T1>(a + b);
}


int main()
{
    // T1 = int, T2 = double, T3 = double
    int r1 = Add<int>(0.5, 0.8);

    // T1 = double, T2 = float, T3 = double
    double r2 = Add<double, float>(0.5, 0.8);

    // T1 = float, T2 = float, T3 = float
    float r3 = Add<float, float, float>(0.5, 0.8);

    cout << "r1 = " << r1 << endl;     // r1 = 1
    cout << "r2 = " << r2 << endl;     // r2 = 1.3
    cout << "r3 = " << r3 << endl;     // r3 = 1.3

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值