STL容器的共通能力和共通操作
2015-08-08 09:15
267 查看
一:容器的共通能力:
所有STL容器都必须满足三个最核心能力:
1: 所有STL容器提供的都是value语义而非reference语义;即容器进行元素的安插操作是,内部实施的是拷贝操作,置于容器中,因此要求容器的每一个元素都能够被拷贝;如果打算存放的对象不具有public copy构造函数,或者想要的不是复制出来的副本,那么容器元素类型就只能是(指向对象)指针类型;
2:总体而言,所有元素形成一个次序(order),也就是说,我们可以依相同次序一次货多次遍历每个元素。每个容器都提供了可返回迭代器的函数,运用这些迭代器就可以遍历元素,这是STL算法赖以生存的关键接口;
3:一般而言,各项操作并非绝对安全,调用者必须确保传给操作函数的参数符合需求,违反这些需求(比如使用非法索引)会导致未定义行为,通常STL不会自己抛出异常,对于异常的检查与处理得小心注意;
二:容器的共通操作
简单测试代码:
参考资料:
C++标准程序库 侯捷 / 孟岩 译
所有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++标准程序库 侯捷 / 孟岩 译
相关文章推荐
- 4 IoC容器的依赖注入(2)
- 【Win 10应用开发】实现全屏播放的方法
- 【Win10 应用开发】OCR识别
- 【Win10应用开发】协议-下篇:自定义多个协议
- 【Win10 应用开发】解决VS 2015 RC不能调试手机应用的问题
- php 生成饼状图,折线图,条形图 通用类
- c#中如何在cshtml页面实现js调用cs变量(mvc模式)
- 树莓派2引脚
- hdu 4612 Warm up (手动扩栈,求树上哪两个点的距离最远)
- 【Win 10开发】协议-上篇:自定义应用协议
- 【Win10 开发】读取PDF文档
- 背包九讲(转载)
- 【Win 10应用开发】SplitView控件
- 【Win 10应用开发】SplitView控件
- Java中的正则表达式
- Summary for week4
- 【Win 10应用开发】认识一下UAP项目
- SpringMVC接收请求参数和页面传递参数
- Mybatis
- POJ 1273 && HDU 1532 Drainage Ditches(最大流-Dinic)