C++ 泛型编程

2024 年 8 月 28 日 | 阅读 6 分钟

C++ 泛型编程简介

使用 C++ 模板,泛型编程模式将方法通用化,以便可以与各种数据类型一起使用。我们不是指定实际数据类型,而是在模板中提供一个占位符,该占位符在编译期间被使用的数据类型替换。因此,如果模板函数被用于整数、字符和浮点数,编译器将生成 3 份函数副本。由于 C++ 使用静态类型,这是可行的。

使用模板的方法

让我们简要回顾一下标准编程,以便理解模板的使用。C++ 编程语言要求所有数据都存储在容器中。这些在技术上称为数据类型,例如 int、float、用户定义等。

无论坐标是以整数还是浮点整数形式提供,计算两个坐标之间距离的过程都将保持不变,因为我们知道该技术对于多种数据形式可能相同。int 数据类型不能存储浮点值,并且将浮点数据类型用于 int 值是内存浪费,因此在 C++ 编程中,我们必须为每种数据类型编写单独的方法。因此,C++ 中的模板为这个问题提供了一个通用解决方案。

概述

使用模板编写 C++ 数据类型无关的代码。在编译时,一个称为代码实例化的过程会导致代码中给定的占位符被实际数据类型替换。Generics 指的是定义为模板的类或函数,而在 C++ 中,“泛型编程”一词指的是整个概念。

函数模板用于编写具有泛型类型(可以根据函数调用期间提供的数据类型更改其行为)的函数。这使我们能够更简单地在多个数据类型上执行相同的操作而无需代码重复。

函数模板用于编写具有泛型类型(可以根据函数调用期间提供的数据类型更改其行为)的函数。这使我们能够更简单地在多个数据类型上执行相同的操作而无需代码重复。

输出

5
4.5
???..
Process executed in 0.11 seconds
Press any key to continue.

说明

在上面的示例中,数据类型与函数调用本身一起提供,但这一步可以避免,因为编译器会根据我们传递给函数的值来推断它。

泛型数据类型

通过类型参数化的类或函数称为泛型类型。使用 C++ 模板可以实现这一点。泛型数据类型是使用模板参数构建的。我们提供一些模板参数,函数将它们作为类型值获取,这与函数参数的概念类似。

以下是语法

可以使用 typename 或 class 关键字。两种策略是等效的。

声明和定义必须在同一文件中

模板中没有普通的函数。它们只在具有某些模板输入的实例期间编译。使用提供的参数和模板,编译器会生成精确的功能。由于模板只在必要时编译,因此不可能将模板函数的定义和声明分离到两个文件中。

重载函数模板

模板函数可以重载。如果程序中发生特定的函数调用,编译器将查找重载函数的精确定义。如果找到,重载函数将运行。如果没有,匹配的模板函数将运行。此外,如果函数调用没有伴随模板函数,编译器将抛出错误。

输出

Inside Template 5.9
Inside Overload 10
???????????..
Process executed in 0.11 seconds
Press any key to continue.

说明

  • 调用 sum(2.1,3.8) 会导致编译器查找不存在的精确函数,然后查找存在的模板函数,以便它可以执行。
  • 对于不同的函数调用 sum(5,5),存在一个用于精确数据类型的重载函数。因此,模板函数将不会被调用。

模板递归函数

可以使用模板函数实现递归,从程序执行的角度来看,一切都像普通递归函数一样运行。

带有用户定义类型的函数模板

我们可以决定在函数模板的模板参数中传递的任何类型。这意味着用户定义类型也可以用于创建函数模板。

输出

Vikram Sharma is 21 years old.
???????????..
Process executed in 0.11 seconds
Press any key to continue.

说明

  • Base 是我们构建的用户定义类型。它有一个函数 toString() { [native code] } 函数,一个函数 Object() { [native code] },以及一些私有实体。
  • 然后有一个函数模板,可以通过使用适当的用户定义数据类型调用它来打印数据。
  • 当编译器解析调用 printDataofbase(b1) 时,将创建具有特定数据类型的模板函数的副本,并且此调用将调用该模板函数的副本,其中 T 被 Person 替换。

类模板

与函数模板一样,类也可以使用模板,使其与其他数据类型兼容。您可能已经使用 C++ 编程中的 vector 创建了一个动态数组,并且您可以看到它与您在 > 中传递的任何数据类型(例如 vector < int >)完美运行。这完全归功于类模板。

类模板和友元函数

友元函数是定义在类外部的非成员函数,它可以访问类的受保护和私有成员。它们用于连接类和函数。在类模板中,我们可以指定我们的友元函数是模板函数还是普通函数。

类模板和静态函数

在 C++ 中,类可以包含静态变量或非静态变量(实例)。类的对象各自包含非静态变量。但是,由于静态变量在所有对象中都是常量,因此所有新对象也共享它。当我们谈论 C++ 模板时,需要记住的一件事是,模板类中的静态变量继续由所有相同类型的对象共享。