跟Google学写代码--Chromium/base--stl_util源码学习及应用
来源:互联网 发布:广联达软件下载教程 编辑:程序博客网 时间:2024/06/09 05:16
Ttile: Chromium/base–stl_util源码学习及应用
Chromium是一个伟大的、庞大的开源工程,很多值得我们学习的地方。
今天与大家分享的就是Chromium下base中的stl_util,是对stl的补充,封装,更有利于我们的使用,完全可以移植到自己的C++工程项目中来。
1 释放STL内存
Clears internal memory of an STL object.
我们知道,vector的clear()方法式清除了vector中的内容,但是vector object所占的内存不会清除。
因此,std_util中有个这个方法:
template<class T>void STLClearObject(T* obj) { T tmp; tmp.swap(*obj); // Sometimes "T tmp" allocates objects with memory (arena implementation?). // Hence using additional reserve(0) even if it doesn't always work. obj->reserve(0);}
也就是使用swap,之前写过一篇博客:
《实战c++中的vector系列–正确释放vector的内存(clear(), swap(), shrink_to_fit())》
地址:http://blog.csdn.net/wangshubo1989/article/details/50359750
2 释放容器内的指针对象
这里隐藏了一个巨大的坑儿,就是迭代器的失效问题,之前也有博客里面介绍过:
《实战c++中的vector系列–可怕的迭代器失效(vector重新申请内存)》
地址:http://blog.csdn.net/wangshubo1989/article/details/50334297
《实战c++中的vector系列–可怕的迭代器失效之二(删除vector中元素)》
地址:http://blog.csdn.net/wangshubo1989/article/details/50334503
template <class ForwardIterator>void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) { while (begin != end) { ForwardIterator temp = begin; ++begin; delete *temp; }}
3 正确删除容器内pairs对象
template <class ForwardIterator>void STLDeleteContainerPairPointers(ForwardIterator begin, ForwardIterator end) { while (begin != end) { ForwardIterator temp = begin; ++begin; delete temp->first; delete temp->second; }}
4 删除容器内pairs对象中的第一个元素
template <class ForwardIterator>void STLDeleteContainerPairFirstPointers(ForwardIterator begin, ForwardIterator end) { while (begin != end) { ForwardIterator temp = begin; ++begin; delete temp->first; }}
5 删除容器内pairs对象中的第二个元素
template <class ForwardIterator>void STLDeleteContainerPairSecondPointers(ForwardIterator begin, ForwardIterator end) { while (begin != end) { ForwardIterator temp = begin; ++begin; delete temp->second; }}
6 vector转为数组
一定要注意,vector可能为空的情况下。
template<typename T>inline T* vector_as_array(std::vector<T>* v) { return v->empty() ? NULL : &*v->begin();}
template<typename T>inline const T* vector_as_array(const std::vector<T>* v) { return v->empty() ? NULL : &*v->begin();}
7 string转为数组
还是是要注意string为空。
inline char* string_as_array(std::string* str) { // DO NOT USE const_cast<char*>(str->data()) return str->empty() ? NULL : &*str->begin();}
8 查找关联容器中是否有某个特定的key
没什么好说的,提高效率,函数的参数为const引用类型。
template <typename Collection, typename Key>bool ContainsKey(const Collection& collection, const Key& key) { return collection.find(key) != collection.end();}
9 判断容器是否有序
这里用到了adjacent_find,在一个数组中寻找两个相邻的元素;
template <typename Container>bool STLIsSorted(const Container& cont) { // Note: Use reverse iterator on container to ensure we only require // value_type to implement operator<. return std::adjacent_find(cont.rbegin(), cont.rend(), std::less<typename Container::value_type>()) == cont.rend();}
10 获得两个有序容器的不同
这里用到了DCHECK,是自己定义的宏:
#define DCHECK(condition) \ LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON ? !(condition) : false) \ << "Check failed: " #condition ". "
template <typename ResultType, typename Arg1, typename Arg2>ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) { DCHECK(STLIsSorted(a1)); DCHECK(STLIsSorted(a2)); ResultType difference; std::set_difference(a1.begin(), a1.end(), a2.begin(), a2.end(), std::inserter(difference, difference.end())); return difference;}
11 合并两个有序的容器
template <typename ResultType, typename Arg1, typename Arg2>ResultType STLSetUnion(const Arg1& a1, const Arg2& a2) { DCHECK(STLIsSorted(a1)); DCHECK(STLIsSorted(a2)); ResultType result; std::set_union(a1.begin(), a1.end(), a2.begin(), a2.end(), std::inserter(result, result.end())); return result;}
12 同时包含在两个容器中的元素
set_intersection:同时包含第一个和第二个集合中的元素
template <typename ResultType, typename Arg1, typename Arg2>ResultType STLSetIntersection(const Arg1& a1, const Arg2& a2) { DCHECK(STLIsSorted(a1)); DCHECK(STLIsSorted(a2)); ResultType result; std::set_intersection(a1.begin(), a1.end(), a2.begin(), a2.end(), std::inserter(result, result.end())); return result;}
13 判断一个容器是否包含另一个容器的所有内容
template <typename Arg1, typename Arg2>bool STLIncludes(const Arg1& a1, const Arg2& a2) { DCHECK(STLIsSorted(a1)); DCHECK(STLIsSorted(a2)); return std::includes(a1.begin(), a1.end(), a2.begin(), a2.end());}
应用:
对上面介绍的方法进行简单的使用,看看吧:
#include<iostream>#include<vector>#include<algorithm>#include"stl_util.h"int main(){ std::vector<int> numbers{1, 2, 3, 4, 6}; std::vector<int> numbers1{ 1, 2, 3 ,4}; std::cout << "Test STLIsSorted:{1, 2, 3, 4, 6}" << std::endl; std::cout << std::boolalpha <<STLIsSorted(numbers) << std::endl << std::endl; std::cout << "Test STLSetDifference {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:" << std::endl; std::vector<int> difference_result; difference_result = STLSetDifference<std::vector<int>, std::vector<int>, std::vector<int>>(numbers, numbers1); for(auto iter: difference_result) { std::cout << iter << std::endl << std::endl; } std::cout << "Test STLSetIntersection {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:" << std::endl; std::vector<int> intersection_result; intersection_result = STLSetIntersection<std::vector<int>, std::vector<int>, std::vector<int>>(numbers, numbers1); for (auto iter : intersection_result) { std::cout << iter << " " ; } std::cout << std::endl; std::cout << "Test STLIncludes {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:" << std::endl; std::cout << std::boolalpha << STLIncludes(numbers, numbers1) << std::endl << std::endl; std::cout << "Test STLClearObject:" << std::endl; STLClearObject(&numbers); std::cout << "vector size:" << numbers.size() << std::endl; std::cout << "vector capacity:" << numbers.capacity() << std::endl << std::endl; system("pause"); return 0;}
输出结果:
Test STLIsSorted:{1, 2, 3, 4, 6}trueTest STLSetDifference {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:6Test STLSetIntersection {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:1 2 3 4Test STLIncludes {1, 2, 3, 4, 6} and { 1, 2, 3 ,4}:trueTest STLClearObject:vector size:0vector capacity:0
- 跟Google学写代码--Chromium/base--stl_util源码学习及应用
- 跟Google学写代码--Chromium/base--stl_util源码学习及应用
- 跟Google学写代码--Chromium/base--windows_version源码学习及应用
- 跟Google学写代码--Chromium/base--cpu源码学习及应用
- 跟Google学写代码--Chromium工程中用到的C++11特性
- 跟Google学写代码--Chromium工程中用到的C++11特性(Library Features)
- 跟Google学写代码--Chromium工程中禁止使用的C++11特性
- 跟Google学写代码:使用Fragment构建可变的界面
- 跟Google学写代码:Interacting with Other Apps【Capture Photo from phone】
- 跟Google 学代码:Building Apps with Graphics & Animation
- 跟Google 学代码:Transmitting Network Data Using Volley
- 想用Python学机器学习?Google大神替你写好了所有的编程示范代码
- chromium源码学习
- Chromium Base学习笔记 —— Callback
- Chromium Base学习笔记 —— Weakptr
- 跟Google 学代码 :Building Apps with Content Sharing(跟女神去表白)
- 跟我学写makefile
- 资源 | 想用Python学机器学习?Google大神替你写好了所有的编程示范代码
- 28幻方
- mysql学习笔记01
- 杨辉三角
- 用Visual Studio查看汇编代码
- ubuntu系统安装eclipse
- 跟Google学写代码--Chromium/base--stl_util源码学习及应用
- 进程管理(一)
- QT开发之IP协议
- Android greenDAO的使用,工具类封装
- 对称矩阵的压缩存储
- 牛客:剑指offer:数字在排序数组中出现的次数 (Java)
- 解决友盟分享的报错的利器——debug模式
- 【原创】【NOIP1999】拦截导弹
- Wildfly配置PostgreSQL数据源