首页 技术 正文
技术 2022年11月7日
0 收藏 982 点赞 963 浏览 2049 个字
条款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 替代

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,944
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,470
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,284
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,100
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,730
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,766