函数、类模板

泛型程序设计

算法实现时不指定具体要操作的数据的类型。适用于多种数据结构。

函数模板

Template <class 类型参数1,class类型参数2,…..>

返回值类型 模板名(形参表)

{

函数体;

}

函数模板可以重载,只要它们的形参表不同即可。

C++编译器遵循以下优先顺序:

  • 先找参数完全匹配的普通函数(非由模板实例化而得的函数)
  • 再找参数完全匹配的模板函数
  • 再找实参经过自动类型转换后能匹配的普通函数
  • 上面的都不符合则报错。

可以在函数模板中使用多个类型参数,可以避免二义性。

#include <iostream>

using namespace std;

void M(int &a, int &b)
{
    cout << "M1 is called" << endl;
}

template <class T>
void M(T &a, T &b)
{
    cout << "M2 is called" << endl;
}

template <class T1, class T2>
void M(T1 &a, T2 &b)
{
    cout << "M3 is called" << endl;
}

int main()
{
    int a=0, b=0;
    double c = 0, d = 0;
    int e = 0; float f = 0;
    M(a, b);
    M(c, d);
    M(e, f);
    return 0;
}

运行结果:

类模板

  • 在定义类的时候给它一个/多个参数
  • 这个一个/多个参数表示不同的数据类型

调用类模板时,指定参数,由编译系统根据参数提供的数据类型自动产生相应的模板类。

类模板的定义

Template <类型参数表>

Class 类模板名

{

成员函数和成员变量

}

类型参数表的写法就是:

Class 类型参数1,class 类型参数2,….

  • 类模板里的成员函数,如在类模板外面定义时,

Template<类型参数表>

返回值类型 类模板名<类型参数名列表>::成员函数名(参数表)

{

…..

}

用类模板定义对象的写法如下:

类模板名<真实类型参数表> 对象名(构造函数实际参数表);

如果类模板有无参构造函数,那么也可以只写:

类模板名 <真实类型参数表>对象名;

使用类模板声明对象

编译器由类模板生成类的过程叫类模板的实例化

  • 编译器自动用具体的数据类型替换模板中的类型参数,生成模板类的代码
  • 由类模板实例化得到的类叫模板类。为类型参数指定的数据类型不同,得到的模板类不同。

同一个类模板的两个模板类是不兼容的

Pair<string,int> *p;

Pair<string,double> a;

p=&a//wrong;

类模板与非类型参数

类模板的参数声明中可以包括非类型参数

Template<class T, int elementsNumber >

  • 非类型参数:用来说明类模板中的属性
  • 类型参数:用来说明类模板中的属性类型,成员操作的参数类型和返回值类型。

cArray<int, 50> 和cArray<int , 40>完全是两个类,这两个类的对象之间不能互相赋值。

类模板与继承

  • 类模板派生出类模板,派生类模板的类型参数名列表中应包含基类模板的参数
  • 模板类(即类模板中类型/非类型参数实例化后的类)派生出类模板
  • 普通类派生出类模板
  • 模板类派生出普通类

类模板派生出类模板

Template <class T1, class T2>

Class A

{

T1 v1;T2 v2;

}

Template <class T1, class T2>

Class B:public A<T2, T1>

{

T1 v3;T2 v4;

}

Template<class T>

Class C:public B<T,T>

{

T v5;

}

模板类派生出类模板

Template <class T1, class T2>

Class A{T1 v1; T2 v2};

Template <class T>

Class B :public A<int, double>{T v};

普通类派生出类模板

Class A

{

int    m;

}

Template <class T>

Class B:public A

{

T v;

}

模板类派生出普通类

Template <class T1, class T2>

Class A{T1 v1; T2 v2};

Class B :public A<int ,double>

{

int v;

}

类模板实例:

#include <iostream>
#include <string>

using namespace std;

template <class T1, class T2>
class Pair
{
public:
    T1 key;
    T2 value;
    Pair(T1 key, T2 value) :key(key), value(value) {}
    bool operator <(const Pair<T1, T2> &p) const;
};
template <class T1, class T2>
bool Pair<T1,T2>::operator<(const Pair<T1, T2> &P) const
{
    return (value < P.value);
}
int main()
{
    Pair<string, int> student("Tom", 19);
    cout << student.key << " " << student.value << endl;
    return 0;
}

参考链接:

https://www.coursera.org/learn/cpp-chengxu-sheji

时间: 2024-10-12 20:37:13

函数、类模板的相关文章

c++数组类模板的实现

1.预备知识 (1)模板参数不仅仅可以是类型参数,还可以是数值型参数. 如: template <typename T, int N>//int N就是数值型参数, 要注意这个int类型,因为这里要注意数值型参数的限制,下面有说数值型参数的限制. void func() { T a[N];//使用模板参数来定义局部数组,模板的数值型参数来表示数组的大小. } func<double, 10>();//这样进行使用,数值型参数,也就是第二个参数要是常量,因为这是数值型模板参数的限制造

C++学习笔记36:类模板

类模板的目的 设计通用的类型式,以适应广泛的成员数据型式 类模板的定义格式 template<模板形式参数列表>class 类名称{...}; 原型:template<typename T> class A; 类模板的成员 像普通类的成员一样定义 定义在类中或类外均可,后者需要在类名后列些模板参数,以区别非模板类的成员函数 template<typename T> T A<T>::f(u) 类成员函数的模板 成员函数可以使用其他模板 template<

C++ Primer 学习笔记_80_模板与泛型编程 --类模板成员

模板与泛型编程 --类模板成员 引言: 这一节我们介绍怎样实现前面提到的Queue模板类. 标准库将queue实现为其他容器之上的适配器.为了强调在使用低级数据结构中设计的编程要点,我们将Queue实现为链表.实际上,在我们的实现中使用标准库可能是个更好的决定!!-_-. 1.Queue的实现策略 如图所示,我们实现两个类: 1)QueueItem类表示Queue的链表中的节点,该类有两个数据成员item和next: a. item保存Queue中元素的值,它的类型随Queue的每个实例而变化:

C++ 类模板二(类模版与友元函数)

//类模版与友元函数 #include<iostream> using namespace std; template<typename T> class Complex{ public: Complex(T a,T b); void Print() const//const修饰的是this指针 { cout << this->Real << ":" <<this->Image<< endl; } /*

【C/C++学院】(11)泛型编程/函数模板/类模板

1.泛型编程基础 #include "iostream" using namespace std; void swap(int &a, int &b) { int c; c = a; a = b; b = c; } void swap(float &a, float &b) { float c; c = a; a = b; b = c; } void main() { int a = 1, b = 2; swap(a, b); float a1 = 1,

C++模板学习:函数模板、结构体模板、类模板

C++模板:函数.结构体.类 模板实现 1.前言:(知道有模板这回事的童鞋请忽视) 普通函数.函数重载.模板函数 认识. //学过c的童鞋们一定都写过函数sum吧,当时是这样写的: int sum(int a,int b) { return a+b; } //实现了整数的相加 //如果再想同时实现小数的相加,就再多写个小数的相加.普通实现我就不写了,知道函数重载的童鞋们会这样写: int sum(int a,int b) {//第一个function return a+b;} double su

函数模板与类模板

函数模板,顾名思义,是在生成函数时依照的模板. 有时,我们需要对不同的数据类型做同样的函数操作. 比如:分别对一个int类型数 和 一个double类型数求平方. 这时,虽然都是同样的求平方操作(函数体内代码一样),但是我们必须要编写两个不同的函数,因为处理int类型的函数的参数和返回值类型都应该是int,而处理double类型的函数的参数和返回值都应该是double. 如下:函数体内操作代码一样,设计为重载函数,用相同的函数名,但是参数类型和返回值类型却都不一样,函数需要定义两次. int S

C++提高1 【泛型编程】函数模板 类模板

[本文谢绝转载] [泛型编程] 函数模板 为什么会有函数模板 现象: 函数的业务逻辑一样 函数的参数类型不一样 [最常用]函数模板  显式的调用 [不常用]类型推导 多个参数,参数定义了必须要用 函数模板,实现int类型数组,char字符串排序: 函数模板 与 普通函数的本质区别 函数模板 和 普通函数在一起 的调用型研究: C++是如何支持函数模板机制的? 函数模板机制结论 类模板 类模板的定义 类模板做函数的参数 类模板的派生成普通类 模板类的派生成模板类 复数类,所有函数都写在类的内部,运

类模板和函数模板

函数模板: 函数模板全特化:所谓特化,是指相对普通模板的特化,是另外一个模板.但不是实例,只是模板 template <class T>                                      //普通函数模板,泛型T mymax(const T t1, const T t2){   return t1 < t2 ? t2 : t1;} template <>const char* mymax(const char* t1,const char* t2)  

【C++】C++问题——类模板分离编译、函数对象、智能指针

C++类模板的分离编译 过去很多类模板都是整个类连同实现都放在一个头文件里,像STL库就是遵循这样的策略来实现类模板的.现在的标准正试图矫正这种局面. 在实现中又许多函数模板.这意味着每个函数都必须包含模板声明,并且在使用作用域操作符的时候,类的名称必须通过模板变量来实例化. 比如一个operator=的代码: template <typename Object> const MemoryCell <Object> & MemoryCell<Object>::o