65.9K
CodeProject 正在变化。 阅读更多。
Home

STL 容器、迭代器和谓词研究

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.91/5 (18投票s)

2006 年 12 月 4 日

5分钟阅读

viewsIcon

34669

downloadIcon

518

通过讨论 std::vector 来研究 STL 容器、迭代器和谓词

Sample Image - GoodCode.gif

引言

本文旨在借助 std::vector 介绍 C++ 标准模板库 (STL) 的容器和迭代器。在介绍容器时,本文涵盖了 std::vector 的一些函数用法;在介绍迭代器时,本文涵盖了谓词和函数指针。

容器

容器是容纳其他对象的对象。容器有两种类型:

1. 序列容器:它按顺序存储并允许数据检索。例如,vector 类定义了一个动态数组,deque 创建了一个双端队列,list 提供了一个线性列表。

2. 关联容器:它允许基于键高效地检索值。例如,map 提供对具有唯一键的值的访问。因此,map 存储键/值对,并允许在给定其键的情况下检索值。

容器使用分配器和谓词。

分配器管理内存。每个容器都有为其定义的分配器。分配器管理容器的内存分配。默认分配器是 allocator 类的一个对象,但如果专业应用程序需要,您可以定义自己的分配器。对于大多数用途,默认分配器就足够了。

有些容器使用一种特殊类型的函数,称为谓词。谓词有两种变体:一元和二元。一元谓词接受一个参数,而二元谓词接受两个参数。这些函数返回 true/false 结果。但使其返回 true 或 false 的精确条件由您定义。

容器

描述

所需头文件

Bitset

一组位。

<bitset>

Deque

一个双端队列。

<deque>

列表

一个线性列表。

<list>

映射

存储键/值对,其中每个键仅与一个值相关联。

<map>

Multimap

存储键/值对,其中一个键可能与两个或更多值相关联。

<map>

Multiset

一个集合,其中每个元素不一定是唯一的。

<set>

priority_queue

一个优先队列。

<queue>

队列

一个普通队列。

<queue>

Set

一个集合,其中每个元素都是唯一的。

<set>

堆栈

一个栈。

<stack>

向量

一个动态数组。

<vector>

迭代器

迭代器提供遍历容器中存储元素的能力。它们或多或少是指针。迭代器有五种类型:

1. 随机访问:存储和检索值。元素可以随机访问。

2. 双向:存储和检索值。向前和向后移动。

3. 前向:存储和检索值。只向前移动。

4. 输入:只检索,不存储值。只向前移动。

5. 输出:只存储,不检索值。只向前移动。

除此之外,STL 还支持反向迭代器。它们是双向的或随机访问的。它们向后移动。例如,如果它指向最后一个元素,那么递增指针将指向倒数第二个元素。

让我们以 vector 模板类为例来理解容器、迭代器和谓词

Vector 概述

Vector 是一个容器类,它实现了动态数组,并根据需要增长。vector 的模板规范如下所示:

template <class T, class Aallocator = Allocator <T>>class vector

为了使用 vector,您需要包含 <vector> 头文件。vector 是 std 命名空间的一部分,因此您需要限定名称。这可以通过以下方式实现:

using std::vector;

vector<int> vInts;

或者您可以像这样完全限定名称:std::vector<int> vInts;

Vector 成员函数

函数

描述

赋值

擦除向量并将指定元素复制到空向量中。

at

返回对向量中指定位置元素的引用

back

返回对向量最后一个元素的引用

begin

返回指向容器中第一个元素的随机访问迭代器。

capacity

返回向量在不分配更多存储空间的情况下可以包含的元素数量。

clear

擦除向量的元素

empty

测试向量容器是否为空。

end

返回指向向量末尾之外的随机访问迭代器

erase

从指定位置删除向量中的一个或一系列元素。

front

返回对向量中第一个元素的引用

get_allocator

返回向量使用的分配器类的对象

插入

在向量中指定位置插入一个或多个元素。

max_size

返回向量的最大长度

pop_back

删除向量末尾的元素

push_back

将元素添加到向量的末尾

rbegin

返回反向向量中第一个元素的迭代器

rend

返回反向向量末尾的迭代器

resize

指定向量的新大小

reserve

为向量对象保留最小存储长度。

size

返回向量中元素的数量

swap

交换两个向量的元素。

向量

构造特定大小的向量,或具有特定值的元素,或使用特定分配器,或作为其他向量的副本

Vector 运算符

运算符

描述

operator []

返回对指定位置的<SPAN style="FONT-FAMILY: 'Courier New'">vector 元素的引用。

创建 Vector

vector 容器有几个构造函数。以下是最常用的构造函数:

空的 int 向量

vector<int> vInt;

容纳 10 个 int 的向量

vector<int> vInt(10);

容纳 10 个 int 并初始化为 0 的向量

vector<int> vInt(10, int(0));

从另一个 int 向量构造的向量

vector<int> vIntA(vIntB);

填充 Vector

std::vector<CItem> m_vItem;
m_vItem.push_back(Item);
    

上述代码构造了 m_vItem 向量,该向量将容纳 CItem 类型的对象。push_back 会在向量的末尾添加元素。

访问 Vector 元素

std::vector<CItem>::iterator m_iItem;
for (m_iItem = m_vItem.begin();m_iItem != m_vItem.end(); m_iItem++) 
{
    index = m_List.InsertItem(0,m_iItem->GetNumber());
    m_List.SetItemText(index,1,m_iItem->GetName());
}

上述代码构造了 m_iItem 迭代器。m_vItem.begin() 会将迭代器初始化到向量的开头,并循环直到达到 m_vItem.end()。该代码还将项目添加到列表中。

删除 Vector 元素

std::vector<CItem>::iterator end;
end = std::remove_if(m_vItem.begin(),m_vItem.end(),IsSelected);
m_vItem.erase(end,m_vItem.end());
        

上述代码定义了 end 迭代器。remove_if 会删除 m_vItem.begin() 到 m_vItem.end() 范围内所有 IsSelected 谓词返回 true 的元素。erase() 函数会从向量中擦除所有已删除的对象。

IsSelected 是一个一元谓词。它接受一个参数(CItem 类型的对象)并返回 true 或 false。

结论

本文及其附带的示例项目对于所有刚接触 STL 的开发人员来说都是很好的参考。它也将解决即使是经验丰富的 STL 开发人员的一些基本问题。

参考文献

Herbert Schildt(C++ 完整参考)

© . All rights reserved.