您的位置:首页 > 其它

STL容器的共通能力和共通操作

2015-08-08 09:15 267 查看
一:容器的共通能力:

所有STL容器都必须满足三个最核心能力:

1: 所有STL容器提供的都是value语义而非reference语义;即容器进行元素的安插操作是,内部实施的是拷贝操作,置于容器中,因此要求容器的每一个元素都能够被拷贝;如果打算存放的对象不具有public copy构造函数,或者想要的不是复制出来的副本,那么容器元素类型就只能是(指向对象)指针类型;

2:总体而言,所有元素形成一个次序(order),也就是说,我们可以依相同次序一次货多次遍历每个元素。每个容器都提供了可返回迭代器的函数,运用这些迭代器就可以遍历元素,这是STL算法赖以生存的关键接口;

3:一般而言,各项操作并非绝对安全,调用者必须确保传给操作函数的参数符合需求,违反这些需求(比如使用非法索引)会导致未定义行为,通常STL不会自己抛出异常,对于异常的检查与处理得小心注意;

二:容器的共通操作

// 1: 构造,析构相关
ContType c; // 产生一个空容器
ContType c1(c2); // 长生一个同型容器
ContType c(beg, end); // 赋值[beg,end)区间内的元素,作为容器初值
c.~ContType(); // 删除所有元素,释放内存

// 2:大小相关
c.size(); // 返回容器中的元素数量
c.empty(); // 判断容器是否为空,相当于size()==0
c.max_size(); // 返回元素的最大可能数量

// 3:比较相关
// 对于比较运算符定义的三条规则:
// 1:比较操作的两端(两个容器)必须属于同一型别
// 2:如果两个容器依序相等,则两个容器相等
// 3:采用字典式顺序比较原则来判断某个容器是否小于另一个容器:
//   3.1:两个序列中的元素一一比较,如果两元素不相等,则这两个元素的比较结果就是这两个序列的比较结果;
//   3.2:古国两元素中国的元素数量不同,则元素较少的那个序列小于另一序列;
//   3.3:如果两序列都没有更多的元素可作比较,则这两个序列相等;
c1 == c2; // 判断是否c1等于c2
c1 != c2; // 判断是否c1不等于c2
c1 < c2;
c1 > c2;
c1 <= c2;
c2 >= c2;

// 4:赋值与交换
c1 = c2; // 将c2的所有元素赋值给c1
c1.swap(c2); // 交换c1和c2的数据
swap(c1, c2); // 同上,是个全局函数

// 5:迭代器相关
c.begin(); // 返回一个迭代器,指向第一个元素
c.end(); // 返回一个迭代器,***指向最后元素的下一位置***
c.rbegin(); // 返向一个逆向迭代器,指向逆向遍历时的第一个元素
c.rend(); // 返回一个逆向迭代器,***指向逆向遍历时的最后元素的下一位置***
// 注,任意时候对于*end(),以及*rend()都是属于未定义行为,因此对于end()以及rend()返回的迭代器都不应该对她调用operator*或operator->

// 6:存取相关
c.insert(posByIterator, elem); // 将elem的一份副本安插于posByIterator处,返回值和posByIterator的意义并不相同
c.erase(beg, end); // 移除[beg, end)区间内的所有元素,某些容器会返回未被移除的第一个接续元素,***注意迭代器指示的位置跟着变***
c.clear(); // 移除所有元素,令容器为空
c.get_allocator(); // 返回容器的内存模型


简单测试代码:

#include<iostream>
#include<vector>

using namespace std;

void test()
{
vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_back(6);
v.push_back(7);
v.push_back(8);
v.push_back(9);
vector<int>::iterator begin = v.begin();
vector<int>::iterator end = begin+2;

vector<int> v2(begin, end); // 拷贝的结果是[ )的形式
cout << v2.empty() << endl; // 0

vector<int> v3(v);
cout << v3.size() << " " << v.size() << endl;
cout << v3[4] << " " << v[4] << endl;
cout << v3[8] << " " << v[8] << endl;

// 这里的v2[2]属于越界访问,与常规数组一样不会报错,但访问的数组是不合理的
cout << v[1] << " " << v2[1] <<" " <<  v2[2] << " " << v[0] << " " << v2[0] << endl;
cout << v.size() << " " << v2.size() << endl;

cout << (v > v2) << endl; // 1

// 用于查看迭代器指向的位置改变测试
cout << "before" << *begin << endl;

v.erase(begin, begin+2); // erase的范围是[)的形式
vector<int>::iterator begin1 = v.begin();
cout << "hello " << (begin == begin1) << endl;

// 可以看到erase()后的迭代器指向位置是自动发生改变的,不再指向动作发生前的位置
cout << "after:" << *begin << " " << *begin1 << endl;

cout << v[2] << " after erase " << v.size() << endl;

// v2 = v;
cout << "v.size()= " << v.size() << " v2.size()= " << v2.size() << endl;
// cout << v[1] << " " << v2[1] << endl;
// cout << v[7] << " " << v2[7] << endl;

v.swap(v2);
cout << v.size() << " " << v2.size() << endl;
cout << "v[0]= " << v[0] << " " << "v2[0]= " << v2[0] << endl;
cout << "v[1]= " << v[1] << " " << "v2[1]= " << v2[1] << endl;

}

int main()
{
test();
}


参考资料:

C++标准程序库 侯捷 / 孟岩 译
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: