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

yizhihongxing

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日

相关文章

  • Java实现的汉语拼音工具类完整实例

    Java实现的汉语拼音工具类完整实例攻略 介绍 在这个攻略中,我们将详细讲解如何使用Java实现一个汉语拼音工具类的完整实例。该工具类可以将汉字转换为对应的拼音。 步骤 步骤一:导入依赖 首先,我们需要导入相关的依赖库。在这个例子中,我们将使用第三方库 pinyin4j 来实现拼音转换功能。你可以在Maven或Gradle中添加以下依赖: <depen…

    other 2023年8月19日
    00
  • ubuntu查看pcl库版本

    当然,我可以为您提供有关“Ubuntu查看PCL库版本”的完整攻略,以下是详细说明: Ubuntu查看PCL库版本 在Ubuntu中,如果需要查看PCL的版本,可以使用以下命令: dpkg -l | grep libpcl 该命令将列出所有已安装的libpcl包其版本号。 示例1:查看PCL库的版本号 假设我们已经安装了PCL库,需要查看其版本号。以下是具体…

    other 2023年5月7日
    00
  • Flutter有无状态类与State及生命周期详细介绍

    下面是关于Flutter的无状态类与有状态类及其生命周期方法的详细介绍及示例: Flutter有状态类和无状态类 Flutter中的类可以分为有状态和无状态两种。有状态的类可以通过修改自身的状态来动态改变其外观和行为,而无状态类则不具有这种能力。通常情况下,我们会在页面中使用有状态的类,而在内容单一或无需动态变化的组件中使用无状态的类。 无状态类 无状态类是…

    other 2023年6月27日
    00
  • es7学习教程之fetch解决异步嵌套问题的方法示例

    ES7学习教程之Fetch解决异步嵌套问题的方法示例 在ES7中,我们可以使用Fetch API来进行网络请求,它提供了一种简洁的方式来处理异步操作。在本教程中,我们将学习如何使用Fetch来解决异步嵌套问题,并提供两个示例说明。 1. 使用Async/Await解决异步嵌套问题 在ES7中,我们可以使用Async/Await来处理异步操作,它提供了一种更加…

    other 2023年7月28日
    00
  • C++实现单链表的构造

    首先,我们需要了解单链表的基本概念。单链表是一种数据结构,它由一系列节点组成,每个节点包含两个部分:数据域和指针域。数据域用于存储节点的数据,指针域则指向下一个节点的地址。单链表的最后一个节点的指针域指向空地址,表示链表的结束。 下面就是C++实现单链表的构造的完整攻略: 定义节点结构体 首先我们需要定义一个节点的结构体,它包含两个成员,分别是数据域和指针域…

    other 2023年6月27日
    00
  • 网页版 B 站导致 CPU 占用高的原因分析与解决方案

    网页版 B 站导致 CPU 占用高的原因分析与解决方案 原因分析 使用网页版 B 站时,可能会遇到 CPU 占用率高的问题,这是由于以下原因导致的: Flash 插件过期。网页版 B 站使用 Flash 插件播放视频,而 Flash 插件已经停止更新,过期后容易出现性能问题。 浏览器缓存过多。浏览器缓存太多会导致卡顿,而网页版 B 站播放视频时需要大量缓存数…

    other 2023年6月26日
    00
  • Java中不得不知的Collection接口与Iterator迭代器

    下面我就来讲解一下Java中Collection接口和Iterator迭代器的相关知识点。 什么是Java中的Collection接口 在Java中,Collection接口代表了一组对象,这些对象被称为元素。Collection接口定义了一些常用的操作,例如添加、删除、查找、枚举等。 Collection接口是Java集合框架的核心,主要有List、Set…

    other 2023年6月26日
    00
  • java多态的向上转型的概念及实例分析

    接下来我将为您详细讲解“Java多态的向上转型的概念及实例分析”的攻略。 目录 前言 什么是Java多态 什么是向上转型 实例分析1:父类引用指向子类对象 实例分析2:Java集合中的向上转型 总结 前言 在Java中,面向对象是一个重要的编程思想,而多态性是面向对象编程中最基本的概念之一。其中,向上转型是多态性的核心之一,本文将详细介绍Java多态的概念以…

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