STL学习笔记(二) vector和string
条款13:vector、string优先于动态分配数组
string是basic_string<char>的类型定义
许多string的背后实现都采用了引用计数的技术,可以消除不必要的内存拷贝和不必要的字符拷贝
条款14:使用 reserve 来避免vector容器不必要的重新分配
vector和string的 realloc 的操作分为4部分:
a.分配一块大小为当前容量的某个倍数的新内存,大多数实现中,vector和string的容量每次以2倍增长
b.把容器的所有元素从旧的内存拷贝到新的内存中
c.析构掉旧内存中的对象
d.释放旧内存
注:任何push、insert操作可能导致内存重分配.重分配之后原来的迭代器、指针、引用全部失效
vector、string的4个成员函数:
a.size():容器中现有多少个元素
b.capacity():容器现分配的内存可以容纳的元素总数
c.resize(vector::size_type n):强迫容器改变到包含n个元素的状态
如果n小于当前size(),则容器尾部的元素将会被析构
如果n小于当前capacity(),则通过默认构造函数创建的新元素被添加到容器的末尾
如果n大于当前capacity(),则会重新分配内存
d.reserve(vector::size_type n):强迫容器把它的容量capacity变为至少是n,前提是n不小于当前大小
vector<int> vec;
for (int i = ; i < ; ++i) vec.push_back(i); //导致10次重分配内存, log(1000) vector<int> vec;
vec.reserve();
for (int i = ; i < ; ++i) vec.push_back(i); //循环过程中不会重分配内存
大小(size)和容量(capacity)之间的关系使我们能够预知什么时候插入操作会导致重分配内存
条款15:注意string实现的多样性
string的值可能会被引用计数,也可能不会,很多实现在默认情况下使用引用计数技术
string对象大小的范围可以是一个 char* 指针的大小的1倍到7倍
不同的实现对字符内存的分配有不同的策略
条款16:了解如何把 vector、string数据传给旧的 c—style API
当需要vector容器首地址时(C API常常需要数组首地址)应该使用 &v[0],而不是v.begin() (begin()返回的是指向容器第一个元素的迭代器)
当需要 char* 时,使用 str.c_str();
标准STL容器与C API转换(利用vector容器与数组内存布局的兼容性)
(1) C API 转到 STL容器
size_t fillArray(double* pArray, size_t arraySize);
vector<double> vec(maxNum); vec.resize(fillArray(&v[], vd.size() )); //将 C array数据拷贝到 vector容器
deque<double> d(vec.begin(), vec.end()); //将 C array数据拷贝到 deque容器
list<double> l(vec.begin(), vec.end() ); //将 C array数据拷贝到 list容器
set<double> s(vec.begin(), vec.end() ); //将 C array数据拷贝到 set容器
(2)STL容器 转到 C API
set<double> s;
vector<double> vec(s.begin(), s.end());
void func(&s[], s.size());
条款17:使用"swap技巧"除去多余的容量
vector容器只会自动扩充内存,不会自动缩减
为了避免容器占用不再需要的内存,可以显示地从容器中去除多余的容量:
vector<Widget> vec;
vector<Widget>(vec).swap(vec);
表达式 vector<Widget>(vec) 创建一个临时变量,这个变量是 vec变量的拷贝,相当于: vector<Widget> temp(vec);
临时变量的拷贝是由拷贝构造函数完成的,因为 拷贝构造函数只为所拷贝的元素分配所需要的内存,所以临时变量之中含有vec中size()个元素,没有多余容量
然后对这个临时变量调用swap,临时变量变成原vec(有多余容量),vec变成原临时变量(无多余容量)
语句末尾swap之后的临时变量(有多余容量)被析构,从而释放了原vec中多余的容量,而现vec中无多余容量
同样技巧对string同样适用:
string str;
string(str).swap(str);
注:swap之后,不仅两容器中的元素被交换,同时它们的迭代器、指针、引用全被交换
条款18:避免使用 vector<bool>
vector<bool>是个假容器,并不真的存储 bool,真正存储的是 bool 的紧凑表示,实际上每个 bool 仅占一个二进制bit位,而不是一个字节
应该使用 bitset 替代
STL学习笔记(二) vector和string的更多相关文章
- 【stl学习笔记】vector
vector是定义于namespace std内的template: namespace std { template<class T, class Allocator = allocator& ...
- Effective STL 学习笔记: 多用 vector & string
Effective STL 学习笔记: 多用 vector & string 如果可能的话, 尽量避免自己去写动态分配的数组,转而使用 vector 和 string . 原书作者唯一想到的一 ...
- ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
- C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例
C# 动态生成word文档 本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正. 在工程中引用word的动态库 在项目中,点击项目名称右键-- ...
- muduo学习笔记(二)Reactor关键结构
目录 muduo学习笔记(二)Reactor关键结构 Reactor简述 什么是Reactor Reactor模型的优缺点 poll简述 poll使用样例 muduo Reactor关键结构 Chan ...
- Effective STL 学习笔记 31:排序算法
Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- WPF的Binding学习笔记(二)
原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...
- 标准模板库(STL)学习探究之vector容器
标准模板库(STL)学习探究之vector容器 C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...
- JMX学习笔记(二)-Notification
Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...
随机推荐
- mac重启privoxy命令
重启命令 brew services restart privoxy
- 使用crontab定时执行python文件问题追根溯源
使用crontab执行定时任务不是第一次用,昨天下午设置几个任务,yy里面已存在的任务,修改指定python环境和执行文件路径后,死活到点不执行. 任务设置如下: 15 16 * * * /root/ ...
- win7上安装虚拟机并上网
一.安装Workstation Pro 二.下载CentOS-7-x86_64-DVD-1511.iso包 三.创建新的虚拟机,按照向导安装即可 四.使用cd /etc/sysconfig/netwo ...
- maven项目创建(eclipse配置
Eclipse相关配置: eclipse 设置默认编码为Utf-8 需要设置的几处地方为: Window --> Preferences --> General --> Conten ...
- Windows MinGW 64-bit boost 踩坑
>g++ -Wall -shared -g -DBUILD_DLL main.cpp -ID:\gcc\boost\include\boost-1_69 -LD:\gcc\boost\lib - ...
- Cscope的使用(领略Vim + Cscope的强大魅力)
文章出处:http://blog.csdn.net/dengxiayehu/article/details/6330200 Cscope的使用(领略Vim + Cscope的强大魅力) 1.Cscop ...
- -bash: xx: command not found 在有yum源情况下处理
-bash: xx: command not found 在有yum源情况下处理 yum provides "*/xx" ###"xx"代表某命令 或者 yu ...
- Pomodoro APP
2015.5.23 UITableView 的数据源刷新问题 本次发过来的版本五,实现了活动清单列表(AllEventsTableViewController).活动详情(AllEventsViewC ...
- Swift在1.2版本的变化
从Xcode 6.3 Beta Release Notes看出,Xcode 6.3 Beta包含了很多颇为值得开发者期待的改变,共计50多处改动,同时修改了Objective-C的语法,足见苹果对Sw ...
- 小型LAMP搭建
一.dns的搭建 安装dns服务 yum install bind 修改dns的主配置文件 [root@234c17 named]# vim /etc/named.conf // // named.c ...