【C++ | 泛型编程】C++ 类模板详解

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍 C++的类模板 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
⏰发布时间⏰:

本文未经允许,不得转发!!!



在这里插入图片描述

🎄一、概述

上篇文章 C++函数模板详解 介绍了函数模板,这篇文章接着介绍C++泛型编程的 类模板

下面先了解什么是泛型编程:

泛型编程是一种编程范式,它强调在编写代码时 尽可能地使算法和数据结构独立于所处理的数据类型

在泛型编程中,使用泛型(通常通过模板在 C++ 等语言中实现)来创建可以处理多种不同类型数据的通用函数、类和数据结构,而无需为每种具体的数据类型单独编写重复的代码。其主要优点包括:

  • 提高代码的复用性:一次编写的泛型代码可以用于多种不同的数据类型,减少了重复开发。
  • 增强代码的可读性和可维护性:因为通用的逻辑被集中在一个地方,而不是分散在针对不同类型的多个实现中。
  • 提高程序的灵活性:可以轻松地适应新的数据类型,而无需对现有代码进行大量修改。

✨1.1 什么是类模板?为什么需要类模板?

类模板是类的蓝图或公式,告诉编译器如何生成类和成员函数定义。

为什么需要类模板呢?
有时候我们写的某个类希望它可以处理多个类型的数据。例如你写了一个栈的类来处理int数据,代码如下:

class Stack
{
private:
	enum {MAX = 10};
	int items[MAX];
	int top;
public:
	Stack( ):top(0){}
	
	bool isempty( ) {return top == 0;}
	
	bool isfull( ) {return top == MAX;}
	
	bool push(const int & item)// add item to stack
	{
		if (top < MAX)
		{
			items[top++] = item;
			return true;
		}
		else
			return false;
	}
	
	bool pop(int & item) // pop top into item
	{
		if (top > 0)
		{
			item = items[--top];
			return true;
		}
		else
			return false;
	}
};

如果现在要求你写一个栈类来处理double类型,没有使用类模板的话,我们就需要写很多重复的代码来完成这两个类,但实际上这两个类除了类型,其他都一样。所以,如果写一个类可能处理不同类型的数据,就可以使用类模板来实现。


在这里插入图片描述

🎄二、类模板的定义

类模板定义格式:

template<typename T1, typename T2, ..., typename Tn>
class 类模板名
{
    // 类内成员定义
};

类模板格式说明:
1、关键字template告诉编译器这是一个模板;
2、关键字template后面是 类型参数列表,使用<>括起来,目的是实例化时给类模板传递类型;
3、编写类代码,需要用到类型相关的,就使用 类型参数列表 的 T1、T2 ... Tn 来替换。
4、成员函数如果在类外定义,则需要加 模板前缀(template<typename T1, typename T2, ..., typename Tn>) 和 类限定符(类模板名<T,T1...Tn>::)。
5、类模板的声明和定义要求放在同一个文件中,通常的做法是放在一个 .h 文件中,使用时就包含进来。

下面使用类模板定义上面的 Stack 类:

template<typename T>
class Stack
{
private:
	enum {MAX = 10};
	T items[MAX];
	int top;
public:
	Stack( ):top(0){}
	bool isempty( ) {return top == 0;}
	bool isfull( ) {return top == MAX;}
	bool push(const T & item);// add item to stack
	bool pop(T & item); // pop top into item
};

// 成员函数类外定义加 模板前缀template<typename T>、类限定符Stack<T>
template<typename T>
bool Stack<T>::push(const T & item)// add item to stack
{
	if (top < MAX)
	{
		items[top++] = item;
		return true;
	}
	else
		return false;
}

// 成员函数类外定义加 模板前缀template<typename T>、类限定符Stack<T>
template<typename T>
bool Stack<T>::pop(T & item) // pop top into item
{
	if (top > 0)
	{
		item = items[--top];
		return true;
	}
	else
		return false;
}

在这里插入图片描述

🎄三、类模板的使用

仅在程序包含模板并不能生成模板类, 而必须请求实例化。

类模板实例化格式:

类模板名<T1,T2...Tn> 类对象;

类模板实例化说明:
1、类模板实例化时必须指定类型参数。格式中的<T1,T2...Tn>就是类模板参数列表。
2、实例化之后,类对象的类型是 类模板名<T1,T2...Tn>,例如,Stack<int> stackInt;中stackInt的类型是Stack<int>

下面使用上面的类模板定义两个类对象,当编译器从我们的 Stack 类模板实例化出一个类时,它会重写 Stack 模板,将模板参数 T 的每个实例替换为给定的模板实参, 在本例中是 int、std::string:

Stack<int> stackInt;
Stack<std::string> stackString;

完整使用例子:

#include <iostream>
#include <stdio.h>
using namespace std;

template<typename T>
class Stack
{
private:
	enum {MAX = 10};
	T items[MAX];
	int top;
public:
	Stack( ):top(0){}
	bool isempty( ) {return top == 0;}
	bool isfull( ) {return top == MAX;}
	bool push(const T & item);// add item to stack
	bool pop(T & item); // pop top into item
};

// 成员函数类外定义加 模板前缀template<typename T>、类限定符Stack<T>
template<typename T>
bool Stack<T>::push(const T & item)// add item to stack
{
	if (top < MAX)
	{
		items[top++] = item;
		return true;
	}
	else
		return false;
}

// 成员函数类外定义加 模板前缀template<typename T>、类限定符Stack<T>
template<typename T>
bool Stack<T>::pop(T & item) // pop top into item
{
	if (top > 0)
	{
		item = items[--top];
		return true;
	}
	else
		return false;
}

int main()
{
	Stack<int> stackInt;
	Stack<std::string> stackString;
	
	for(int i=0; i<10; i++)
	{
		stackInt.push(i);
		char str[10] = {0,};
		sprintf(str, "str_%d", i);
		stackString.push(std::string(str));
	}
	
	cout << "stackInt:" << endl;
	while(!stackInt.isempty())
	{
		int value = 0;
		stackInt.pop(value);
		cout << value << endl;
	}
	
	cout << "stackString:" << endl;
	while(!stackString.isempty())
	{
		std::string value;
		stackString.pop(value);
		cout << value << endl;
	}
	
	return 0;
}

运行结果:
在这里插入图片描述


在这里插入图片描述

🎄四、

在这里插入图片描述

🎄五

在这里插入图片描述

🎄六、

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wkd_007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值