C++之STL初探

STL简介

STL 是"Standard Template Library"的缩写,中文译为"标准模板库"。STL 是 C++ 标准库的一部分。

STL可以说是C++模板的产物,随着C++对模板的支持越来越好,STL就借助模板的力量把常用的数据结构及其算法都实现了一遍,并且做到了数据结构和算法的分离。 从内容上看,STL一个就是容器与算法的大杂烩,并且这些容器和算法都是经过高度优化的,性能极佳。

程序员们通过对STL的学习和使用,可以高价高效灵活地处理一些复杂的数据结构(例如可以用vector代替数组),使得开发者们可以将更多的精力去实现业务逻辑。

通常认为,STL 是由容器、算法、迭代器、函数对象、适配器、内存分配器这 6 部分构成。而容器和算法就是STL中的核心,其他的比如迭代器等都是为了这两部分而服务的。

所谓基础不牢,地动山摇,下面我们先简单来介绍一下STL中的两大核心内容:容器和迭代器。后后续的章节打打铺垫...

STL容器

所谓的容器,我们可以理解为某种数据结构的集合。

STL中的容器又分为两大类:序列容器和关联容器。其中序列容器包括array、vector、deque、list 和 forward_list等。 而关联容器又有map、multimap、set 以及multiset等,在C++11之后又新增了unordered_map、unordered_set等无序的关联容器, 在查询效率上它们比map、set更有效率。

通过以下这张图我们简单地先来了解下STL中容器的大致能力

比如我们看看序列容器vector的简单使用:

c 复制代码
#include <iostream>
#include "vector"

int main() {
    std::vector<int> vec;
    // 放入一个元素
    vec.push_back(1);
    // 放入一个元素,它和push_back有啥区别呢?
    vec.emplace_back(2);
    // 动态数组是否为空
    vec.empty();
    // 插入一个元素
    vec.insert(vec.begin(),100);
    // 元素的个数
    vec.size();
    // 返回第一个元素
    auto a = vec.front();
    std::cout << "a:" << a << std::endl;
    // 最后一个元素
    auto b = vec.back();
    std::cout << "b:" << b << std::endl;
    // 删除一个元素
    vec.erase(vec.begin());
    // 容器变量
    for (auto item:vec) {
        std::cout << "item:" << item << std::endl;
    }
    return 0;
}

你从上面的实例中有没有感觉STL的便捷呢?更多关于STL的容器的具体用法我们在后面单独章节再给大家一一介绍...

STL迭代器

无论是那种容器,我们在开发过程中使用最多的便是对容器的增删改查,为了使得这一工作更加统一方便,可以使用STL中的迭代器来操作。

就笔者理解而言,笔者认为迭代器其实就是一种高阶的指针运算,它可以只想容器的中的元素,通过迭代器可以对容器中的元素进行访问和遍历,甚至是修改。

而迭代器又可以分为五种迭代器,分别为输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器。

同样,以下这张图也简单总结了一下五种迭代器的能力:

在上面的五种迭代器中,其中输入迭代器和输出迭代器比较特殊,它们不是把数组或容器当做操作对象,而是把输入流/输出流作为操作对象。

STL中虽然有5中迭代器,但是并不是说所有的容器都能使用这五种迭代器,有可能有些容器仅支持五种迭代器中的某几种,需要开发者具体情况具体分析。

尽管这些迭代器有着不同的能力,但是这些迭代器有都着较为统一的定义方式,它们的定义格式一般如下

容器类名::iterator 迭代器名;

和C++中的常量类似,一个迭代器也可是常量迭代器,对于非常量迭代器和常量迭代器的区别一般就是可读写和只读的关系。

例如有一个正向迭代器容器类名::iterator 迭代器名;那么它对应的常量迭代器则是器类名::const_iterator 迭代器名;

简单的代码实例:

c 复制代码
#include <iostream>
#include "vector"
#include <iomanip>

int main() {
    std::vector<std::string> vec;
    vec.emplace_back("hello");
    vec.emplace_back("world");
    // 正向迭代器
    std::vector<std::string>::iterator it = vec.begin();
    // 使用迭代器比较
    while (it != vec.end()){
        // *it获取迭代器指向内容
        std::cout << "stringContent:" << *it << std::endl;
        ++it;
    }
    std::cout << "###########华丽的分割线############"<< std::endl;
    // 反向迭代器
    std::vector<std::string>::reverse_iterator r_it = vec.rbegin();
    // 使用迭代器比较
    while (r_it != vec.rend()){
        // *it获取迭代器指向内容
        std::cout << "stringContent:" << *r_it << std::endl;
        ++r_it;
    }

    return 0;
}

输出内容如图:

好了,关于STL的概述先了解到这里,后续会针对STL中的各种容的详细使用以及各种主要避坑事项再做分解学习,关注我,后期不定期更新...

相关推荐
会编程的小孩20 小时前
C++ qt的安装
c++
计算机魔术师1 天前
做前端 UI 的人,接下来得先过一道开源技能的"设计质检"
编程语言
小成202303202651 天前
C++~07补充
开发语言·c++
hold?fish:palm1 天前
40 二叉树的直径
c++·leetcode
解决小子1 天前
【虚幻引擎】【C++】【GAS框架】构建角色基类、属性集、数值钳制
c++·笔记·游戏引擎·虚幻·gas·能力系统
lunar_coder1 天前
【C++】如何解决智能指针的析构函数,如何实现shared_ptr的引用计数以及解决shared_ptr的循环引用
c++·1024程序员节
白白白小纯1 天前
C++进阶.多态
c++
凯瑟琳.奥古斯特1 天前
力扣1016高效解法:剪枝优化技巧
开发语言·c++·算法·leetcode·职场和发展
xiangyun611 天前
C++ priority_queue 底层:手撕二叉堆与 Top K 问题
c++·算法·面试·stl·1024程序员节
坤坤子吖1 天前
C++继承:友元、静态成员、多继承与组合
开发语言·c++·笔记·学习·1024程序员节