c++模板的概念全新解释(一)

简介: c++模板的概念全新解释(一)

前言


我们都知道在c++与c语言的区别中,最大的不同就是c++訲多了对象和模板,前面我们介绍了面向对象的编程,现在我们来认识一下c++中模板的知识。

模板八函数或类要处理的数据类型参数化,即表现为数据的多态性。在面向对象技术中,模板是另一种代码重用机制。


提示:以下是本篇文章正文内容,下面案例可供参考


一、模板的概念


强类型的严格性和灵活性


在强类型程序设计语言中,参与运算的所有对象的类型在编译时即可确定下来,并且编译程序将进行严格的类型检查,这样就可以在程序未运行之前就检查出类型不兼容的错误。

但是由于这种强类型语言在提高程序的可靠性的同时又带来了一些负作用。

例如我们在使用函数求某一个计算类容的时候,会出现参数类型不一样,他们的算法相同,但是参数不同,所以程序员就必须写两个程序。这就不利于程序的扩展和维护。


解决冲突的路径


如何解决强类型的严格性与灵活性的冲突?以往有三种方法。

第一种:利用宏函数,使用宏函数虽然确实会简便问题,但是我们知道引入宏函数后可能会导致程序出现以些意想不到的问题。所以在c++中一般不会使用宏函数。

第二种:为各种类型重载这一函数,但是重载函数又显得麻烦。增加工作量。

第三种:放松类型检查,在编译期间忽略这些类型的匹配问题。而在运行期间进行类型匹配检查,但是在程序运行的时候可能会出现类型不兼容的错误。

综和上面的方法,我们发现无论何种方法,都会有漏洞,那么最理想的方法是什么?最理想的方法是直接将数据类型作为类的参数,就像函数可以将数据作为参数一样。这种机制叫做“类属”(genericity),强类型程序设计语言(如Ada,Eiffel等语言)通常都采用这种方式


模板的概念


模板是一种参数化多态性的工具,可以为逻辑功能相同而类型不同的程序提供代码共享的机制。

由于c+程序结构的主要构件是类和函数,所以在c++中,模板被分为函数模板和类模板。模板并非一个实实在在的函数或类,仅仅是函数或类的描述,模板运算对象的类型不是实际的数据类型,而是一种参数化的类型(又称为类属类型)。带类属参数的函数叫做函数模板,带类属参数的类叫做类模板。


9c9581ef7f469a73bae5f8815148fb15_16818e1d73e54aff902d10d8a52bb4de.png


一(1).函数模板


通常,设计的算法是可以处理多种数据类型的,c++提供的函数模板可以一次定义出具有共性(除类型参数外,其余全相同)的一组函数,同时也可以处理多种不同类型数据的函数。从而大大增强了函数设计的通用性。


函数模板的定义


函数模板定义的格式:

template<模板参数表>

<返回值类型><函数名>(<参数表>)

{

<函数体>

}

其中,关键字template是定义模板的关键字,<模板参数列表>中包含一个或多个用逗号分开的模板参数项,每一项又保留字class或者typename开始,后跟用户命名的标识符,此标识符为模板参数,表示数据类型。函数模板中可以利用这些模板参数定义函数返回值类型,参数类型和函数体中的变量类型。它同基本数据类型一样,可以在函数中的任何地方使用。


d04b09c92e4f5d90eb0dd348ce67e934_292f5e6689534adfba313c82c9076b86.png


函数模板的实例化


#include<iostream>
#include<string>
using namespace std;
template <typename T>  //函数模板;
T Max(T a, T b)
{
  return a > b ? a : b;
}
int main()
{
  int a, b;
  cout << "Input two integers to a&b:" << endl;
  cin >> a >> b;
  cout << "max(" << a << "," << b << ")=" << Max(a, b) << endl;        //有些编译软件不能使用max模板函数,是由于系统自带max函数;
  char c, d;
  cout << "Input two chars to c&d:" << endl;
  cin >> c >> d;
  cout << "max(" << "\'" << c << "\'" << "," << "\'" << d << "\'" << ")=";
  cout<< Max(c, d) << endl;
  float x, y;
  cin >> x >> y;
  cout << "Input two float x&y:" <<endl;
  cout << "max(" << x << "," << y << ")=" << Max(x, y) << endl;
  cout << "Input two string to p&h:" << endl;
  string p, h;
  cin >> p >> h;
  cout << "max(" << "\"" << p << "\"" << "," <<"\"" << h <<"\"" << ")=";
  cout << Max(p, h) << endl;
  return 0;
}


9cab85c9c2ec0298f466320f033b6c1f_e8f93ad9e14744f69dc27d71e80cc789.png



在程序中,我们可以发现在使用相同的函数时,不再需要多次定义数据类型,编译器会根据语句中的实际数据类型而产生相应的函数。

这就极大的减轻了程序员的工作负担。

下面我们来看看他的图示:


d6596a42e717bcd422800a6df55ac924_2845b7ec1b7f4d0ba669f458c7b29c03.png


函数模板的声明和定义必须是全局作用域,而且模板不能被声明成类的成员函数。


函数模板的重载

函数模板有多种重载方式,可以定义同名的函数模板,提供不同的参数和实现;也可以用其他非模板函数重载。


1.函数模板的重载


重载函数模板和重载函数类似,重载函数模板便于定义类属参数,或者函数参数的类型。个数不同所进行的操作。


#include<iostream>
using namespace std;
template <typename T>
T Max(T a, T b)
{
  return a > b ? a : b;
}
//重载;
template<typename T>
T Max(T a[], T n)
{
  T temp;
  temp = a[0];
  for (int i = 0; i < n; i++)
  {
  if (temp < a[i])
    temp = a[i];
  }
  return temp;
}
int main()
{
  int a, b;
  cout << "Input two integers to a&b" << endl;
  cin >> a >> b;
  cout << "Max(" << a << "," << b << ")=" << Max(a, b) << endl;
  int i, aa[10] = { 3,7,9,11,0,6,7,5,4,2 };
  cout << "The original array:" << endl;
  for (i = 0; i < 10; i++)
  {
  cout << aa[i] << ",";
  }
  cout << endl;
  cout << "Max of 10 integers is" << Max(aa, 10) << endl;
  return 0;
}



2.用普通函数重载函数模板


函数模板实例化时,实际参数类型将替换模板参数,虽然这种参数替换具有类型检查功能,但是却没有普通传值参数的类型转换机制。

也就是说,函数模板没办法预知隐式的类型转换。这个时候我们就可以用非模板函数重载一个同名的函数模板;


#include<iostream>
using namespace std;
template <typename T>
T Max(T a,T b)
{
  return a > b ? a : b;
}
int Max(int a, float b)            //用普通函数重载函数模板;
{
  return a > b ? a : b;
}
int main()
{
  char a = '4', b = '5';
  float c = 5.7;
  int d = 10;
  cout<<Max(a, b) << endl;
  cout << Max(d, c) << endl;
  return 0;
}


3.用特定函数重载函数模板


#include<iostream>
#include<cstring>
using namespace std;
template <typename T>
T Max(T a, T b)
{
  return a > b ? a : b;
}
int Max(int a, float b)
{
  return a > b ? a : b;
}
char* Max(char* a,char* b)
{
  return strcmp(a, b) > 0 ? a : b;
}
int main()
{
  char a = '4', b = '5';
  int c = 5;
  cout << "Max(" << "\'" << a << "\'" << "," << "\'" <<b << "\'" << ")=";
  cout << Max(a, b) << endl;
  cout << "Max(" << "\'" << a << "\'" << "," << "\'" << c << "\'" << ")=" << Max(a, c) << endl;
  const char* p, * h;
  p = "qaz";
  h = "wsx";
  cout << "Max(" << "\"" << p << "\"" << "," << "\"" << h << "\"" << ")=" << Max(p,h) << endl;
}


类模板


同函数模板一样,使用类模板可以为类定义一种模式,使得类中的某些数据成员。某些成员函数的参数以及某些成员函数的返回值能取任意类型。类模板是对一批仅有成员数据类型不同类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,然后给出一套程序代码,就可以用来生成多种具体的类,即模板类。

目录
打赏
0
0
0
0
12
分享
相关文章
㉿㉿㉿c++模板的初阶(通俗易懂简化版)㉿㉿㉿
㉿㉿㉿c++模板的初阶(通俗易懂简化版)㉿㉿㉿
|
5月前
|
C++ STL 初探:打开标准模板库的大门
C++ STL 初探:打开标准模板库的大门
149 10
|
8天前
|
【c++】模板详解(2)
本文深入探讨了C++模板的高级特性,包括非类型模板参数、模板特化和模板分离编译。通过具体代码示例,详细讲解了非类型参数的应用场景及其限制,函数模板和类模板的特化方式,以及分离编译时可能出现的链接错误及解决方案。最后总结了模板的优点如提高代码复用性和类型安全,以及缺点如增加编译时间和代码复杂度。通过本文的学习,读者可以进一步加深对C++模板的理解并灵活应用于实际编程中。
25 0
深入理解C++模板编程:从基础到进阶
在C++编程中,模板是实现泛型编程的关键工具。模板使得代码能够适用于不同的数据类型,极大地提升了代码复用性、灵活性和可维护性。本文将深入探讨模板编程的基础知识,包括函数模板和类模板的定义、使用、以及它们的实例化和匹配规则。
【C++11】可变模板参数详解
本文详细介绍了C++11引入的可变模板参数,这是一种允许模板接受任意数量和类型参数的强大工具。文章从基本概念入手,讲解了可变模板参数的语法、参数包的展开方法,以及如何结合递归调用、折叠表达式等技术实现高效编程。通过具体示例,如打印任意数量参数、类型安全的`printf`替代方案等,展示了其在实际开发中的应用。最后,文章讨论了性能优化策略和常见问题,帮助读者更好地理解和使用这一高级C++特性。
143 4
【C++】模板详细讲解(含反向迭代器)
C++模板是泛型编程的核心,允许编写与类型无关的代码,提高代码复用性和灵活性。模板分为函数模板和类模板,支持隐式和显式实例化,以及特化(全特化和偏特化)。C++标准库广泛使用模板,如容器、迭代器、算法和函数对象等,以支持高效、灵活的编程。反向迭代器通过对正向迭代器的封装,实现了逆序遍历的功能。
55 3
|
4月前
|
【c++】模板详解(1)
本文介绍了C++中的模板概念,包括函数模板和类模板,强调了模板作为泛型编程基础的重要性。函数模板允许创建类型无关的函数,类模板则能根据不同的类型生成不同的类。文章通过具体示例详细解释了模板的定义、实例化及匹配原则,帮助读者理解模板机制,为学习STL打下基础。
53 0
【C++打怪之路Lv7】-- 模板初阶
【C++打怪之路Lv7】-- 模板初阶
38 1
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
121 2
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
100 0
C++入门6——模板(泛型编程、函数模板、类模板)
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等