C++ 中的类模板继承
本文将讨论 C++ 中最流行和最常用的方法之一(即类模板)。
C++ 中模板的添加带来了一种新的编码范式,称为通用编程。 现在,这是 C++ 程序员工具包的一个重要元素,是许多标准库的基础,也是我们许多新 C++ 开发者以前从未遇到过的东西。
泛型编程有时与面向对象编程中的继承概念形成对比。 另一方面,真正的多范式方法需要研究两者如何相互作用。
C++ 中的模板
在 C++ 中,模板是一个基本但功能强大的工具。 基本思想是将数据类型作为参数传递,从而无需为多种数据类型编写相同的代码。
例如,软件业务可能需要对多种数据类型进行 sort()。 我们可以构造一个单一的 sort() 函数并将数据类型作为参数传递,而不是编写和维护大量代码。
C++ 添加了两个新关键字来支持模板:template 和 typename。 关键字 class 始终可以用来代替第二个关键字。
句法:
template <typename T>
void myFunction(T var )
{
//function definition
}
在上面显示的语法中,我们可以看到,为了定义接受模板变量作为参数的函数,我们添加了一行 template
模板在 C++ 中如何工作
模板在编译过程中会扩展。 这与宏类似。
另一方面,编译器在模板扩展之前执行类型检查。 这个概念很简单:源代码仅包含一个函数或类,而生成的代码可能具有同一函数或类的多个副本。
下面的示例对此进行了详细说明。
#include<iostream>
using namespace std;
template <typename T>
T checkMaxValue (T a, T b)
{
if (a > b)
return a;
else if (b > a)
return b;
else
return 0;
}
//driver program
int main()
{
cout << checkMaxValue (102,204)<<endl; //int value
cout << checkMaxValue ('c','f') <<endl; // char value
}
请注意,我们在驱动程序的第一行中向函数传递了两个整数,它最终将返回两个整数中的最大值。 我们在第二行将两个 char 值传递给同一个函数,该函数将返回最大的 char 值。
在编译时,我们调用该函数,如下所示:
int checkMaxValue (int a, int b)
对于第二次调用,我们编写以下内容:
char checkMaxValue (char a, char b)
我们可以看到,根据调用函数时传递的变量类型,在编译时创建了同一函数的多个副本。
我们可以使用函数和类的模板。 我们将讨论这两种类型以及如何实现这两种类型。
C++ 中的函数模板
我们将创建一个可以处理各种数据类型的通用函数。 Sort()、max()、min() 和 printArray 是函数模板的示例。
示例代码:
template <class T>
void sortArray(T arr[], int s)
{
for (int i = 0; i < s - 1; i++)
for (int j = s - 1; i < j; j--)
if (arr[j] < arr[j - 1])
{
int var = arr[j];
arr[j] = arr[j-1];
arr[j-1] = var;
}
cout << " Sorted array : ";
for (int i = 0; i < s; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver Code
int main()
{
int a[5] = { 10, 50, 30, 40, 20 };
int n=5;
sortArray<int>(a, n);
char c[5] = {'g','a','i','h','e'};
sortArray<char>(c, n);
return 0;
}
输出:
在代码片段中,我们创建了一个函数 sortArray(),它可以接受数组的模板类型和该数组的大小值并打印排序后的数组。 我们在主代码中为两种不同的数组类型调用了它:int 和 char 数组。
因此,我们可以使用任何数据类型,并且相同的函数都可以工作。 它节省了时间和空间,并且在通用编程中也很高效。
C++ 中的类模板
当类定义不依赖于数据类型的内容时,类模板与函数模板一样非常方便。 LinkedList、BinaryTree、Stack、Queue、Array 和更多类可以从类模板中受益。
句法:
template <class T>
class className {
private:
T a;
... .. ...
public:
T myFunc(T x);
... .. ...
};
在此语法中,T 是用作数据类型占位符的模板类型。 当为此模板类创建对象时,使用以下语法:
className<dataType> objectName;
同样,我们可以使用以下语法来编写它:
className<int> objectName;
className<double> objectName;
示例:
#include<iostream>
using namespace std;
template <class T>
class Number {
private:
T numb;
public:
Number(T a) : numb(a) {}
T get() {
return numb;
}
};
int main() {
Number<int> integerNumber(50);
Number<double> doubleNumber(8.9);
cout << "integer Number = " << integerNumber.get() << endl;
cout << "double Number = " << doubleNumber.get() << endl;
return 0;
}
输出:
您可以在这个示例中看到,同一个类可以接受整数和双精度数。 这个例子非常通用,可以让您理解类模板的概念。
这个概念可以扩展,许多类可以使用 LinkedList、Stack、Queue 等模板来实现。
C++ 中的类模板继承
从模板类继承是可行的。 所有常规继承和多态性规则均适用。
如果我们需要新的派生类具有通用性,则必须将其设为模板类,并将模板参数发送到基类。 这是因为继承只能通过类来实现,而模板不是类,除非通过向其传递某种数据类型来实例化模板。
句法:
template <class T>
class derived : public Base<T>{};
输出:
#include <iostream>
using namespace std;
template<class T>
class Base {
private:
T val;
public:
void setVal(T a)
{
val = a;
}
};
template<class T>
class Derived : public Base<T> {
public:
void setVal (T b)
{
Base<T>::setVal(b);
}
};
int main()
{
Derived<int> a;
a.setVal(4);
return 0;
}
我们在代码片段中创建了一个基类模板,其中包含模板类型变量和成员函数。 此外,我们创建了一个派生类,它也是一个类模板并扩展了基类模板。
当扩展Base类时,我们必须指定模板变量,如Base<T>
。 基类是泛型的,派生类也是泛型的。
派生类也可以有其模板参数。 前面的示例可以修改如下:
template<class T , class S>
class Derived : public Base<T> {
private:
S data;
public:
void setVal (T b)
{
Base<T>::setVal(b);
data = b;
}
};
所以,我们可以看到继承也可以使用类模板来实现。 此外,我们可以使用类模板来实现多态性和适配器类。
相关文章
Arduino 复位
发布时间:2024/03/13 浏览次数:315 分类:C++
-
可以通过使用复位按钮,Softwarereset 库和 Adafruit SleepyDog 库来复位 Arduino。
Arduino 的字符转换为整型
发布时间:2024/03/13 浏览次数:181 分类:C++
-
可以使用简单的方法 toInt()函数和 Serial.parseInt()函数将 char 转换为 int。
Arduino 串口打印多个变量
发布时间:2024/03/13 浏览次数:381 分类:C++
-
可以使用 Serial.print()和 Serial.println()函数在串口监视器上显示变量值。