C++ Primer 笔记——容器

1.标准库中定义了一些顺序容器,所有顺序容器都提供了快速顺序访问元素的能力。

2.如果容器的元素类型没有默认构造函数,那么在构造这个容器的时候不能只指定这个容器的数目,因为没有办法默认构造这些元素。

3.常见的一些容器操作

4.当一个容器初始化另一个容器拷贝时,两个容器的元素类型必须完全匹配,如果用一个容器的迭代器去初始化另一个容器时,只要元素类型可以转换即可。

5.当定义一个array时除了指定类型之外还要定义它的大小,array可以进行拷贝赋值。

std::array<int, 3> arr = {1, 2, 3};
std::array<int, 3>::iterator iter;
std::array<int, 3> arr1 = arr;

6.容器的赋值运算。

7.assign(array不可用)可以为类型不同但是相容的容器赋值。

std::list<std::string> names;
std::vector<const char*> oldstyle;
names = oldstyle;        // 错误,类型不同
names.assign(oldstyle.cbegin(), oldstyle.cend());

8.除array外,swap不对任何元素进行拷贝,删除或插入操作,因此可以保证在常数时间完成。

  • 元素不被移动意味着,除string外,指向容器的迭代器,引用和指针在swap操作之后都不会失效,但是已经指向的容器已经随着元素发生变化。
  • 对string调用swap会导致迭代器,引用和指针失效。
  • swap两个array会真正交换它们的元素,因此交换两个array所需的时间与array的元素数目成正比,而且指针,引用和迭代器所绑定的元素保持不变,但元素的值变了。

9.关系运算符两边的运算对象必须是相同类型的容器,且必须保存相同类型的元素。而且只有当元素类型定义了相应的比较运算符才可以比较,比较方式和string类似。

10.除array外,所有标准库容器都提供灵活的内存管理。

11.当我们用一个对象来初始化容器时,或将一个对象插入到容器中时,实际上放入到容器中的是对象值得一个拷贝。

12.在新标准下,接受元素个数或范围的insert版本返回指向第一个新加入元素的迭代器,如果范围为空,不插入任何元素,insert操作会将第一个参数返回。

std::list<int> ls;
int i;
auto iter = ls.begin();
while (std::cin >> i)
    iter = ls.insert(iter, i);    // 等价于调用push_front

13.emplace函数在容器中直接构造元素,传递给emplace函数的参数必须与元素类型的构造函数相匹配。

14.在顺序容器中访问元素的操作如下,而且下面操作返回的都是引用,如果容器是const的对象,则返回值是const引用。

15.顺序容器的删除操作。

16.在一个forward_list中添加或删除元素的操作是通过改变给定元素之后的元素来完成的,所以forward_list没有insert,emplace和erase,而是定义了一些其他操作。

17.除了array外,可以用resize来增大或缩小容器。如果当前大小大于所要求大小,则多余的会被删除,反之会增加新元素到尾部。

18.向容器中添加或删除元素可能会使指向容器元素的指针,引用或迭代器失效。

向容器添加元素之后 :

  • 如果容器是string或vector,且存储空间被重新分配,则都会失效,如果未重新分配,则指向插入位置之前的仍然有效,插入位置之后的会失效。
  • 对于deque,插入到除首尾位置之外的任何位置都会失效,如果在首尾位置添加元素,迭代器会失效,但指向存在元素的指针和引用不会失效。
  • 对于list和forward_list,仍然有效。

从容器中删除元素后:

  • 对于vector和string,指向被删除元素之前的仍然有效。注意:尾后迭代器总是会失效。
  • 对于deque,如果在首尾位置之外的任何位置删除元素,指向被删除元素外其他元素的会失效,如果删除的是尾元素,则尾后迭代器会失效,但其他的不受影响。如果删除首元素,也不会受影响
  • 对于list和forward_list,仍然有效。

19.范围for语句体内不应该改变其所遍历序列的大小,因为一旦添加或删除元素,用来判断结束的end()函数的值可能变得无效了。

20.vector元素的存储是连续的,当增加元素的时候如果连续的内存空间不够,则会重新分配空间。string和vector通常会预留空间作为预备。定义vector对象的时候设定其大小也就没什么必要了,事实上如果这么做性能可能更差。只有一种例外情况,就是所有元素的值都一样。

21.管理容量的成员函数。

reserve至少会分配指定大小的空间,但是可能更大,而且当参数小于当前容量的时候,reserve什么也不做。

shrink_to_fit只是一个请求,标准库并不保证退还内存。

只有在insert操作时size()和capacity()相等或调用reserve时才会重新分配内存,会分配多少取决于实现。

22.修改string的操作。

23.string的搜索操作。

时间: 2024-08-29 23:20:22

C++ Primer 笔记——容器的相关文章

C++ Primer笔记 容器和算法(1)

C++ 容器和算法(1) "泛型算法": 1.      算法可以作用于不同的容器类型. 2.      容器容纳多种不同类型元素 顺序容器: vector list deque(全称double-ended queue) 适配器: stack queue priority_queue 定义: vector<string> svere; C c(b,e)当[b,e) 左开右闭之间的元素. C c(n,d)初始化n个d 复制构造  vector<int> ivec

C++ Primer笔记 容器和算法(2)

erase 删除后  返回的是删除元素的后一个迭代器位置 int main() { //怎样正确的删除全部元素 循环 int a[]={1,2,3,4,5,6,7,8,9}; vector<int> v(a,a+6); for(vector<int>::iterator it=v.begin();it!=v.end();) { it=v.erase(it); } for(vector<int>::iterator it=v.begin();it!=v.end();it+

C++ Primer笔记7_STL之关联容器

关联容器 与顺序容器不同,关联容器的元素是按关键字来访问和保存的.而顺序容器中的元素是按他们在容器中的位置来顺序保存的. 关联容器最常见的是map.set.multimap.multiset map的元素以键-值[key-value]对的形式组织:键用作元素在map中的索引,而值则表示所存储和读取的数据. set仅包含一个键,并有效的支持关于某个键是否存在的查询. pair类型 首先介绍下pair,pair定义在utility头文件中,一个pair保存两个数据成员,类似容器,pair是一个用来生

C++ Primer笔记5_STL之顺序容器

1.STL(Standard Template Library) 标准模板库.从根本上说,STL是一些"容器"的集合,这些"容器"有list, vector,set,map等,STL也是算法和其它一些组件的集合.这里的"容器"和算法的集合指的是世界上很多聪明人很多年的杰作.每一个C++程序员都应该好好学习STL.大体上包括container(容器).algorithm(算法)和iterator(迭代器),容器和算法通过迭代器可以进行无缝连接. 2

C++ Primer笔记8_动态内存_智能指针

1.动态内存 C++中,动态内存管理是通过一对运算符完成的:new和delete.C语言中通过malloc与free函数来实现先动态内存的分配与释放.C++中new与delete的实现其实会调用malloc与free. new分配: 分配变量空间: int *a = new int; // 不初始化 int *b = new int(10); //初始化为10 string *str = new string(10, ); 分配数组空间: int *arr = new int[10];//分配的

C++ Primer笔记6_STL之泛型算法

1.泛型算法: 大多数算法定义在头文件algorithm中,标准库还在头文件numeric中定义了一组数值泛型算法 只读算法: 举例: find函数用于找出容器中一个特定的值,有三个参数 int val = 10;//val为我们需要查找的值 auto result = find(vec.begin(), vec.end(), val): cout << "The value "<< val << (result == vec.end() ? &qu

C++ Primer 笔记 第三章

C++ Primer 第三章 标准库类型 3.1using声明 例: using namespace atd; using std::cin; 3.2string类型 初始化方式 string s1 默认构造函数,s1为空串 string s2(s1) 将s2初始化为s1的一个副本 string s3(“value”) 将s3初始化为一个字符串的副本 string s4(n, 'c') 将s4初始化为字符'c'的n个副本 getline读取整行文本 getline接受两个参数:一个是输入流对象和

C++ Primer笔记12_运算符重载_递增递减运算符_成员访问运算符

1.递增递减运算符 C++语言并不要求递增递减运算符必须是类的成员.但是因为他们改变的正好是所操作对象的状态,所以建议设定为成员函数. 对于递增与递减运算符来说,有前置与后置两个版本,因此,我们应该为类定义两个版本的递增与递减运算符. 问题来了,程序是如何区分前置和后置呢?因为都是++和-- 为了解决这个问题,后置版本的递增递减运算符接受一个额外的(不被使用)int类型的形参.当我们使用后置运算符时,编译器为这个形参提供一个值为0的实参.这个形参唯一的作用就是区分前置和后置运算符函数. 因为不会

C++ Primer笔记2_四种类型转换_异常机制

1.类型转换 命名的强制类型转换: 有static_cast.dynamic_cast.const_cast.reinterpret_cast static_cast: 编译器隐式执行的任何类型转换都可以由static_cast完成 当一个较大的算术类型赋值给较小的类型时,可以用static_cast进行强制转换. 可以将void*指针转换为某一类型的指针 可以将基类指针强制转换为派生类指针,但是不安全. 无法将const转化为nonconst,这个只有const_cast才可以办得到 举例: