《C++ Primer》读书笔记-第九章 02 容器支持的操作

作者:马志峰
链接:https://zhuanlan.zhihu.com/p/24297619
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

声明:

  • 文中内容收集整理自《C++ Primer 中文版 (第5版)》,版权归原书所有。
  • 原书有更加详细、精彩的释义,请大家购买正版书籍进行学习。
  • 本文仅作学习交流使用,禁止任何形式的转载

正文

  1. 容器都是模板类
  2. 迭代器
  3. begin和end函数
  4. 定义和初始化
  5. 赋值和swap
  6. 容器大小
  7. 关系运算

模板类

list<int>  
deque<double>

也可以定义容器的容器,

vector<string>  
vector<vector<string>>

迭代器

迭代器范围 [begin, end)

end指向尾后元素,begin可以通过递增到达end

这种范围的约定使得我们能简单安全的遍历容器

while( begin != end )
{
    cout << *begin << endl;
    ++begin;
}

连额外的判空操作都不需要了,若begin == end,则范围为空,循环不会执行

begin和end函数

  • begin返回起始迭代器
  • cbegin 返回const迭代器
  • rbegin 返回反向迭代器

容器中实际有两个名为begin的函数

  • 一个是const成员,返回容器的const_iterator
  • 一个是非const成员,返回容器的iterator
iterator begin();
const_iterator begin() const;

因此下面的类型判断

auto itr = a.begin();

仅当a是const时,itr是const_iterator

定义和初始化

将一个容器创建为另一个容器的拷贝有两种方法

  1. 直接拷贝整个容器(要求两个容器的容器类型和元素类型都匹配)
  2. 拷贝由迭代器对指定范围内的元素(只要求元素可以转换就可以了)
C c1(c2);
C c1 = c2;

C c( beg, end );

列表初始化

list<string> authors = {"a", "b", "c"};
vector<const char*> articles = {"a", "b", "c"};

顺序容器特有的构造函数

接受一个容器大小和初始值(可选)

vector<int> ivec(10, -1);
list<string> svec(10, "hi");
forward_list<int> ivec (10);

array不支持这种方式

array的构造

与内置数组一样,容器大小是array类型的一部分

array<int, 42> arr;
array<int, 42>::size_type i;
array<int, 10> ia1;
array<int, 10> ia2 = {0,1,2,3,4,5,6,7,8,9};
array<int, 10> ia3 = {42};

与内置数组不同的是,array支持拷贝和赋值

赋值和swap

c1 = c2;

赋值后,c1中元素的个数和值都与c2中相同

赋值完成后,两个容器之间有关联吗?

对于array来说,长度是类型的一部分,要求类型一致才能赋值

array<int, 10> a1 = {0,1,2,3,4,5,6,7,8,9};
array<int, 10> a2 = {0};
a1 = a2;

array<int, 10> a2 = {0};
a2 = {0};

是非法的。array不接受列表赋值

这里也体现出初始化和赋值是两码事

  • 初始化调用的是构造函数
  • 赋值调用的运算符重载函数

assign

顺序容器还定义了名为assign的成员

  • seq.assign(beg, end) 将迭代器范围内的元素赋值给容器
  • seq.assign(il) 将初始化列表中的元素赋值给容器
  • seq.assign(n,t) 将容器中的元素替换为n个值为t的元素

array也不支持assign

swap

如果两个容器类型相同,可以用swap交换他们的内容

而且swap比赋值和assign这种元素拷贝操作要快的多,因为它只改变容器的数据结构

----------itr1-----------  
-----------↓-------------  
svec1→{A0, A1, A2,A3}  
svec2→{B0, B1, B2, B3, B4}

swap后

----------itr1-----------  
-----------↓-------------  
svec2→{A0, A1, A2,A3}  
svec1→{B0, B1, B2, B3, B4}

swap只是容器的结构发生了改变,之前的迭代器等指向的元素不发生变化。只是元素属于另外一个容器了

string是一个例外,调用swap会导致迭代器、引用和指针失效

array更加特殊,它的swap是真正的元素交换

----------itr1-----------  
-----------↓-------------  
arr1→{A0, A1, A2,A3}  
arr2→{B0, B1, B2, B3, B4}

swap后

arr1→{B0, B1, B2, B3, B4}  
arr2→{A0, A1, A2,A3}
-----------↑------------- 
----------itr1-----------

容器大小操作

size
empty
max_size

容器关系运算

只有相同类型的容器才能进行比较操作

猜你喜欢

转载自blog.csdn.net/qq_26751117/article/details/53576870