C++中模板和STL介绍详解

C++中模板和STL介绍详解

一、模板

1.1 模板的概念

模板是C++中的一种特殊的机制,可以帮助我们实现通用的重复使用的代码。相当于对代码进行了泛化处理,将一些具体类型变成参数供调用的时候注入不同的类型,大大提高了代码的复用性。

1.2 模板的语法

模板有两种类型:函数模板和类模板。函数模板定义的函数可以用于不同类型的参数,类模板定义的类也可以用于不同数据类型的参数。

  1. 函数模板:

函数模板的定义方式如下:

template <typename T>
T add(T x, T y) {
    return x + y;
}

其中,typename代表类型别名,可以换成class

<T>中的T是一个类型参数列表,函数的自变量中可以使用T来表示类型参数,返回值使用T表示。

注:模板不可以分离到.h文件以外!

调用方式:

int main()
{
    int a = 1, b = 2;
    cout << add(a, b) << endl; // 3
    double c = 1.5, d = 2.5;
    cout << add(c, d) << endl; // 4
    return 0;
}
  1. 类模板:

类模板的定义方式如下:

template <typename T>
class Stack {
public:
    void push(T);
    T pop();
private:
    T elements[20];
    int size;
};

template <typename T>
void Stack<T>::push(T x) {
    if (size == 20) {throw "overflow";}
    elements[size++] = x;
}

template <typename T>
T Stack<T>::pop() {
    if (size == 0) {throw "underflow";}
    return elements[--size];
}

其中,<T>中的T是一个类型参数列表,类的成员函数中可以使用T来表示类型参数。

调用方式:

int main()
{
    Stack<int> s1;
    s1.push(1);
    s1.push(2);
    s1.push(3);
    cout << s1.pop() << endl; // 3
    cout << s1.pop() << endl; // 2
    cout << s1.pop() << endl; // 1

    Stack<double> s2;
    s2.push(1.5);
    s2.push(2.5);
    s2.push(3.5);
    cout << s2.pop() << endl; // 3.5
    cout << s2.pop() << endl; // 2.5
    cout << s2.pop() << endl; // 1.5
    return 0;
}

二、STL

2.1 STL的概念

STL(Standard Template Library),是C++语言中的标准模板库,包含了大量的模板类和函数,可以提供通用的程序设计解决方案,使程序员在开发应用程序时可以少写代码,减少出错的可能。它提供了序列容器、关联容器、迭代器、算法和函数对象等各种组件,是C++工业界的核心和基础。

2.2 STL的组件

常用的STL组件有:

  • 容器:vector,list,deque,set,multiset,map,multimap等容器,主要负责存储和管理元素。
  • 迭代器:输入迭代器,输出迭代器,前向迭代器,双向迭代器,随机访问迭代器。
  • 算法:常用算法有:sort,search,foreach,find等,是对元素进行处理的代码片段。
  • 函数对象:普通函数、函数指针、函数对象。是重载了括号运算符的对象,可看作函数指针。

2.3 STL之容器详解

以下以vector、list、set为例,讲解STL中常见容器的使用方式:

  1. vector

vector是一个基于表达式的序列容器,是数组和链表的混合体,支持随机访问等高效操作,插入和删除元素时需要移动大量数据,所以效率较低。

定义一个vector容器:

vector<int> v1;

常用函数:

v1.push_back(10);        // 增加尾元素
v1.pop_back();           // 删除尾元素
v1.insert(v1.begin(), 2);// 在第一个元素前插入2
v1.erase v1.begin();     // 删除第一个元素
v1.clear();              // 删除所有元素
v1.empty();              // 容器是否为空
v1.size();               // 容器中元素的个数
  1. list

list是一个基于表达式的链表容器,支持在序列的任意位置高效的插入和删除操作,但是访问操作的效率不高。

定义一个list容器:

list<int> l1;

常用函数:

l1.push_back(10);        // 增加尾元素
l1.pop_back();           // 删除尾元素
l1.push_front(2);        // 增加头元素
l1.pop_front();          // 删除头元素
l1.insert(l1.begin(), 2);// 在第一个元素前插入2
l1.erase l1.begin();     // 删除第一个元素
l1.clear();              // 删除所有元素
l1.empty();              // 容器是否为空
l1.size();               // 容器中元素的个数
  1. set

set是一个基于红黑树的关联容器,元素自动排序,也可以自定义排序规则,支持查找、删除、插入等操作,但是不支持随机访问。

定义一个set容器:

set<int> s1;

常用函数:

s1.insert(10);        // 增加元素
s1.erase(10);         // 删除元素
s1.clear();           // 删除所有元素
s1.empty();           // 容器是否为空
s1.size();            // 容器中元素的个数

三、示例说明

3.1 示例一

  • 功能:

定义一个栈模板类,能够存取任意数据类型的元素,并能进行进栈、退栈操作。使用vector作为底层存储结构,支持动态扩容。

  • 代码实现:
template <typename T>
class Stack {
public:
    void push(T);
    T pop();
    int size();
private:
    vector<T> elements;
    int top = 0;
};

template <typename T>
void Stack<T>::push(T x) {
    elements.push_back(x);
    top++;
}

template <typename T>
T Stack<T>::pop() {
    if (top == 0) { throw "underflow"; }
    top--;
    T result = elements[top];
    elements.pop_back();
    return result;
}

template <typename T>
int Stack<T>::size() {
    return top;
}

3.2 示例二

  • 功能:

使用STL中的set容器实现一个单词计数器。

  • 代码实现:
void WordCount(string str)
{
    istringstream iss(str); // 将整个字符串转化为字符流
    set<string> s;
    while (!iss.eof()) // 以空格为分隔符将字符串分割成单词写入set中
    {
        string word;
        iss >> word;
        s.insert(word);
    }
    for (set<string>::iterator it = s.begin(); it != s.end(); it++) // 排序输出
    {
        int count = count_if(iss.begin(), iss.end(), [&](char c) {return c == *it[0]; });
        cout << *it << ":" << count << endl;
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++中模板和STL介绍详解 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • hbuilderx全局搜索

    HBuilderX全局搜索 HBuilderX是DCloud公司推出的一款跨平台的多端开发IDE,不仅能够支持Web、App等前端开发,还支持Flutter、Vue等多种语言。作为一款强大的前端开发工具,搜索功能是其不可或缺的一个部分。 在HBuilderX中,全局搜索是一个非常实用且重要的功能。当代码量较大且层级复杂时,我们通常需要进行全局搜索以快速找到指…

    其他 2023年3月29日
    00
  • linux系统安装rsync和sersync实现数据实时同步详细步骤(rsync实时同步)

    以下是实现Linux系统安装rsync和sersync实现数据实时同步的详细步骤攻略: 1. 安装rsync和sersync 首先需要在Linux系统上安装rsync和sersync。可以使用以下命令安装: sudo apt-get install rsync sersync 2. 创建同步目录 在rsync和sersync之间进行同步需要一个同步的目录。可…

    other 2023年6月27日
    00
  • java是什么?

    Java是什么? Java是一种面向对象的编程语言,具有简单、健壮、可移植、安全和高性能等特性。Java可以在不同的平台上运行,并且具有广泛的应用领域,在移动应用、Web应用、企业应用等方面都有广泛应用。 Java的特性 Java的特性包括: 简单性:Java语言具有简单、结构化的语法,易于学习和理解。 面向对象性:Java是一种面向对象的编程语言,具有封装…

    其他 2023年4月16日
    00
  • 【python】shellmd5使用的那些事

    【Python】shellmd5使用的那些事 shellmd5是一个Python库,用于计算文件的MD5值。它可以在命令行中使用,也可以在Python脚本中使用。本文将提供一个完整攻略,包括安装、使用方法、示例说明等。 1. 安装 使用pip命令可以轻松安装shellmd5库。在命令行中输入以下命令即可: pip install shellmd5 2. 使用…

    other 2023年5月8日
    00
  • Win11更新后无法调节亮度怎么办 Win11亮度条消的解决办法

    下面是详细的攻略: 问题描述 在升级到Win11后,有些用户发现无法调节屏幕亮度的问题,甚至在屏幕亮度条消失了。这给用户带来了很大的不便,因为调节屏幕亮度是非常重要的。接下来,我将提供一些Win11亮度条消失的解决办法。 解决办法 1. 通过设备管理器更新显卡驱动程序 有时,屏幕亮度条消失的原因是因为显卡驱动程序过时或损坏。在这种情况下,我们可以通过设备管理…

    other 2023年6月27日
    00
  • c/c++内存分配大小实例讲解

    C/C++内存分配大小实例讲解 在C/C++中,我们可以使用malloc和free函数来动态分配和释放内存。这些函数允许我们在程序运行时根据需要分配所需大小的内存。下面是一个详细的攻略,将介绍如何在C/C++中进行内存分配和释放,并提供两个示例说明。 1. 使用malloc函数分配内存 malloc函数用于在堆上分配指定大小的内存块。它的函数原型如下: vo…

    other 2023年8月1日
    00
  • css预处理器sass使用教程(多图预警)

    CSS预处理器Sass使用教程(多图预警) 什么是Sass Sass是一款强大的CSS预处理器,它将CSS语言扩展得更加灵活和强大,可以帮助开发者更加高效地编写CSS代码。Sass提供了一系列的功能和特性,如变量、嵌套规则、MIXIN、函数、循环等,可以让我们更加方便的编写复杂的样式表。 安装Sass 如果你想在项目中使用Sass,首先需要安装它。安装可以选…

    其他 2023年3月28日
    00
  • python算法题 链表反转详解

    Python算法题-链表反转详解 1. 题目描述 给定一个单链表,将其翻转。例如: 输入: 1 -> 2 -> 3 -> 4 -> None 输出: 4 -> 3 -> 2 -> 1 -> None 2. 解法分析 链表是一种动态数据结构,它不要求内存必须按照线性顺序连续分布,相对于数组来说,它更加灵活。 链表…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部