Skip to content

Latest commit

 

History

History
70 lines (42 loc) · 4.88 KB

13.md

File metadata and controls

70 lines (42 loc) · 4.88 KB

十三、C++ 标准库

简介

C++ 标准库中的内容比我们有时间讨论的要多得多。我们将只关注一些我们还没有探索过的最常用的特性。

迭代器

迭代器的作用与 IEnumerable 和中的相关接口相同。NET,例如提供一种在集合中导航的通用方法。例如,给定一个std::vector,您可以使用以下代码循环遍历它的项目集合:

          vector<int> vec;
          vec.push_back(1);
          vec.push_back(4);
          vec.push_back(7);
          vec.push_back(12);
          vec.push_back(8);

          for (auto i = begin(vec); i != end(vec); i++)
          {
                wcout << *i << endl;
          }

std::begin函数提供了一个指向集合第一项的迭代器。std::end提供一个迭代器,表示我们已经到达集合的末尾;集合的最后一个项目,假设集合中有任何项目,是std::end给我们的项目之前的一个项目。这就是为什么我们在for循环中检查!=。如果集合中没有项目,则std::beginstd::end将返回相同的值。

除了这两个模板函数的迭代器之外,许多集合还通过名为cbegincend的成员函数提供const迭代器,通过rbeginrend提供反向迭代器(反向循环遍历集合),通过crbegincrend提供const反向迭代器。在前面的例子中,你可以用vec.rbegin()替换begin(vec),用vec.rend()替换end(vec),反向遍历向量。

基于范围的for循环

C++ 11 增加了一种额外类型的for循环,称为基于范围的for循环,它提供的功能类似于 C# 中的foreach循环。基于范围的for循环使用迭代器,省去了去引用指针的麻烦,也省去了错误检查结束的可能性。基于范围的for循环相当于前面示例中的for循环,如下所示:

          for (auto item : vec)
          {
                wcout << item << endl;
          }

std::vector和其他容器

你最有可能使用的收藏是std::vector。它是一个快速的通用集合,类似于. NET 中的List<T>,可以在<vector>头文件中找到。

要在向量末尾添加一个项目,使用成员函数push_back。要从向量末尾移除一个项目,请使用pop_back。您可以像访问数组一样,使用[]访问索引处的项目。要在特定的从零开始的索引处添加元素或元素范围,请使用insert成员函数。要删除特定从零开始的索引处的元素或元素范围,请使用erase成员函数。

C++ 11 中增加的一个简洁特性是emplaceemplace_back成员函数提供的就地构造功能。与其构造一个对象,然后使用insertpush_back将其添加到向量中,不如调用emplace_back并简单地将传递给构造器的参数传递给向量持有的类型。然后,该向量将构建并添加一个新的对象实例,而不需要进行复制或移动带来的额外计算,也不需要使用额外的本地内存。

emplace函数的工作原理是一样的,除了你首先给它传递一个指定位置的迭代器。您可以使用cbegin()cend()向矢量的开头或结尾添加项目。如果你有一个特定的从零开始的索引想要放置一个物品,你可以使用vec.cbegin() + idx。如果你想在一个项目的末尾放置一些空格,你也可以从cend()中减去。

vector提供了更多的功能,所以你肯定应该进一步探索。例如,at成员函数会在索引处给你一个项目。有一些方法可以告诉向量调整它的内部容量,这样你就有更多的空闲空间——例如,如果你知道你需要正好 125 个项目——或者这样你就最小化了内存使用——如果你添加了它将需要的所有元素并且内存限制很紧。

除了std::vector,几个类似的容器有不同的用例。std::vector当您需要极其快速、随机的访问时,它本身就是最佳选择,因为您通常会在集合的最末端添加和删除项目。如果你也需要经常在收藏前添加物品,可以考虑使用std::deque代替。

先入先出容器使用std::queue。使用std::stack作为后进先出容器。

std::map类提供了一个排序的字典。std::unordered_map提供哈希表。

std::set类是一个排序的键控集合,其中存储的项是它自己的键,因此每个元素必须是唯一的。std::unordered_setstd::set的未排序的等价物。

std::list类提供了一个双向链表。std::forward_list提供单链表。

<algorithm>表头

<algorithm>表头包含了很多非常有用的功能:比如findsortcopy之类的东西,以及它们所有的相关方法。学习它们的最好方法是用它们做实验。

C 运行时库

C 运行时库中的一些功能可能很有用。一般来说,访问库最好的方式就是包含相关的<c_____>头文件,比如<cstdlib>