第九章 顺序容器
1、顺序容器的构造函数可接受大小参数,但是如果该容器存储的元素没有默认构造函数,需要我们提供元素初始化器。
class A{
public:
A(int v):v(v){}//无默认构造函数
int v;
};
int main()
{
vector<A> v(10,1);//可以
//vector<A> v1(10);//不可以值提供一个元素数目参数
return 0;
}
2、一个容器初始化另一个容器的拷贝。
创建一个容器为另外一个容器的拷贝时,两个容器的类型及其元素必须匹配。
但是当列表初始化,或者迭代器初始化时,就不需要完全匹配,只要可以转化过去就行。
int main(){
double a[] = {1.1,1.2,1.3};
vector<int> v0(begin(a),end(a));
for(auto x:v0)cout << x << endl;
vector<double>v1(v0);//错误。类型不匹配
}
3、赋值和swap。
容器类型可以使用 = 号直接赋值,但是赋值会导致左边容器内部的迭代器,引用和指针失效。而swap操作不会。
swap操作:容器内元素并未交换。原来的迭代器指向的元素属于不用的容器了。
4、容器关系运算符
每个容器都支持和!=。除了无序关联容器外的所有容器都支持关系运算符(>,>=,<,<=)。
相等与否用的是元素的运算符,大小比较用的是元素的<运算符。所以如果元素没有定义这两种运算符,或者这两种运算符不是public的,那么将不能比较。
5、使用insert的返回值:插入的第一个元素的迭代器。
vector<int> v1{4,5,6},v2{3,2,1};
auto it = v1.begin();
for(auto x:v2)it = v1.insert(it,x);//1.2.3.4.5.6
for(auto x:v1)cout << x << "\t";
6、使用emplace操作。P308
emplace — insert
emplace_back — push_back
emplace_front — push_front
**emplace成员直接在容器管理的内存中直接构造元素,而push_back会创建一个局部临时对象,并将其压入内存中。
back(),front(),[],at()。返回的都是引用。
vector<int> v{1,2,3};
auto &x = v.back();
x = 666;
cout << v[2];//666
auto &y = v.at(1);
y = 888;
cout << v[1];//888
8、删除元素
pop_back(),pop_front(),erase(),clear()。
erase()返回一个指向被删除元素之后元素的迭代器。
删除deque中除首尾之外的任何元素都会使得所有迭代器、引用和指针失效。指向vecto或string中删除节点之后位置的迭代器,引用和指针都会失效。
删除成员函数并不检查其参数,在删除元素之前,我们必须确保它是存在的。
9、改变容器大小。
我们可以使用resize()增大或缩小容器。
增大的话,值初始化或者提供提供一个构造函数。
缩小的话,可能会使指针或者迭代器失效。
10、容器操作可能使迭代器失效。
1.vector string重新分配空间,则指向容器的迭代器、指针和引用都会失效。
2.插入、删除操作会使得操作之后位置的迭代器失效。
11、vector 是如何增长的
容器大小管理操作:
shrink_to_fit只能用于vector,string,deque
capacity,reserve只能用于vector,string
c.shrink_to_fit(),将capacity()减少为size()相同的大小
c.capacity() 不重新分配内存空间的话,c可以保存多少元素个数
c.reserve(n) 分配至少能容纳n个元素的内存空间,n如果<=capacity(),那么reserve什么也不做;n大于当前容量时,才会分配空间。
c.size() 容器中元素的个数,与capacity是不一样的。
分配策略:
大部分vector采用的分配策略:就是在每次需要分配内存空间时,将当前的容量capacity翻倍;
这也是不确定的,应该具体问题具体分析。
12、string的其他构造方法
1.三个构造函数。
string s(cp,n); cp指向的数组前n个字符的拷贝。此数组至少有n个。
string s(s2,pos); s2下标为pos开始。
string s(s2,pos,len); s2下标为pos开始 长度为len。
2.s.substr(pos,n); 返回一个string,包含从pos开始的n个字符的拷贝。pos的默认值是0。n的默认值是s.size() - pos,即拷贝从pos开始的所有字符。
3.string除了支持顺序容器的赋值运算符以及assign、insert、和erase 操作。除此(接受迭代器)之外,它还定义了额外的insert和erase版本(接受下标)。s.insert(0,s2);
4.replace()函数:
string s = "123";
s.replace(0,1,"---");//从位置0开始删除1个元素,并插入 ---
cout << s << endl;//---23
5.string的搜索操作。
find():
s.find(s1);//查找s中第一次出现s1的位置。
s.rfind(s1);//查找s中最后一次出现s的位置。
13、string与数值之间的转换
to_string(val):一组重载函数,返回val值的string表示。
stoi(s,p,b):返回s的起始子串(表示整数内容)的数值,p:第一个非数字字符的下标,默认值为0;b:转换所有的基数,默认为10。
相似的:stoll(),stoull(),stod(),stof().