首页 / C++ / C++ STL 容器适配器
C++ STL 容器适配器
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C++ STL 容器适配器,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4637字,纯文字阅读大概需要7分钟。
内容图文
![C++ STL 容器适配器](/upload/InfoBanner/zyjiaocheng/1086/2aec2569978c4b138bc5da10c4d9561d.jpg)
目录:
- 实现简单的Vector
- 容器面临的问题
- 容器适配器介绍
- 带有容器适配器的Vector
一 实现简单Vector
#include<iostream> #include<stdlib.h> #include<string.h> #include<string> #include<unistd.h> #include<atomic> usingnamespace std; template<typename T> class Vector { public: Vector(int size):cursize(0),maxsize(size) { vec = new T[size]; } ~Vector() { delete []vec; vec = nullptr; } // 拷贝构造 Vector(const Vector<T> &src):cursize(src.cursize),maxsize(src.maxsize) { vec = new T[src.maxsize]; for(int i = 0;i < src.cursize;i++) { vec[i] = src.vec[i]; } } // 赋值构造函数 Vector<T> & operator = (const Vector<T> & src) { if(this == &src) { return *this; } delete []vec; vec = new T[src.maxsize]; cursize = src.cursize; maxsize = src.maxsize; for(int i = 0; i< cursize; i++) { vec[i] = src.vec[i]; } return *this; } // push_back;void push_back(const T &val) { if(cursize == maxsize) { resize(); } vec[cursize++] = val; } // pop_backvoid pop_back() { if(cursize == 0) { return; } --cursize; } private: T *vec; atomic_int cursize; atomic_int maxsize; void resize() { if(maxsize == 0) { vec = new T[1]; cursize = 0; maxsize = 1; }else { T * tmp = new T[2*maxsize]; for(int i = 0; i < maxsize; i++) { tmp[i] = vec[i]; } delete []vec; maxsize *=2; vec = tmp; } } }; int main() { Vector<int> v(10); cout<<endl; return0; }
二 容器存在的问题
- 定义容器Vector<int> vec(10) 时,我们希望底层开辟10个整型大小的空间,但是不但在开辟空间的同时,还构造了对象,浪费资源
- 调用pop_back时,我们希望是要删除最后一个元素,但是代码上并没有析构,如果这个对象还占有外部资源,那么就会造成内存泄露
- 当vec 的容器出作用域时,还会存在10次的析构,这些都是不合理的
解决办法:
- 当定义容器的时候,我们只需要开辟内存,不用构造无用的对象
- 当pop_back 时不应该只是-- 操作,而应该调用对象的析构函数,是否释放额外的资源
- 当容器vec 析构时,应该把容器的有效对象进行析构,然后在释放整个容器的内存资源。
三 容器适配器
核心就是把容器的内存开辟和对象构造分开,对象析构和内存释放分开,容器适配器主要提供以下函数
空间配置器的函数 | 功能 |
---|---|
allocate | 负责开辟内存 |
deallocate | 负责释放内存 |
construct | 负责在容器中构造对象 |
destroy | 负责析构对象 |
自定义一个简单的空间适配器
#include<iostream> #include<stdlib.h> #include<string.h> #include<string> #include<unistd.h> usingnamespace std; template<typename T> class Myallocator { public: // 开辟内存空间 T * allocator(size_t size) { return (T*) malloc(sizeof(T) * size); } // 释放内存空间void deallocate(void * ptr) { free(ptr); } // 负责对象构造void construct(T *ptr, const T &val) { new ((void*)ptr) T(val); // 定位new 构造对象 } void destory(T *ptr) { ptr->~T(); // 调用对应的析构函数 } };
四 实现一个带有容器适配器的Vector
#include<iostream> #include<stdlib.h> #include<string.h> #include<string> #include<unistd.h> #include<atomic> usingnamespace std; template<typename T> class Myallocator { public: // 开辟内存空间 T * allocator(size_t size) { return (T*) malloc(sizeof(T) * size); } // 释放内存空间void deallocate(void * ptr) { free(ptr); } // 负责对象构造void construct(T *ptr, const T &val) { new ((void*)ptr) T(val); // 定位new 构造对象 } void destory(T *ptr) { ptr->~T(); // 调用对应的析构函数 } }; template<typename T ,typename allocator = Myallocator<T>> class Vector { public: Vector(int size,const allocator &alloc = allocator()):cursize(0),maxsize(size),myallocator(alloc) { vec = myallocator.allocator(size); } ~Vector() { for(int i =0; i< cursize; i++) { myallocator.destory(vec+i); } myallocator.deallocate(vec); vec = nullptr; } // 拷贝构造 Vector(const Vector<T> &src):cursize(src.cursize),maxsize(src.maxsize),myallocator(src.myallocator) { vec = myallocator.allocator(maxsize); for(int i = 0;i < src.cursize;i++) { myallocator.construct(vec+i,src.vec[i]); } } // 赋值构造函数 Vector<T> & operator = (const Vector<T> & src) { if(this == &src) { return *this; } for (int i = 0; i < cursize; ++i) { myallocator.destory(vec+i); } myallocator.deallocate(vec); cursize = src.cursize; maxsize = src.maxsize; vec = myallocator.allocator(maxsize); for(int i = 0; i< cursize; i++) { myallocator.construct(vec+i,src.vec[i]); } return *this; } // push_back;void push_back(const T &val) { if(cursize == maxsize) { resize(); } myallocator.construct(vec+cursize,val); cursize++; } // pop_backvoid pop_back() { if(cursize == 0) { return; } --cursize; myallocator.destory(vec+cursize); } private: T *vec; atomic_int cursize; atomic_int maxsize; allocator myallocator; void resize() { if(maxsize == 0) { vec = new T[1]; cursize = 0; maxsize = 1; }else { T * tmp = myallocator.allocator(2*maxsize); for(int i = 0; i < maxsize; i++) { myallocator.construct(tmp+i,vec[i]); } for(int i =0; i < maxsize; i++) { myallocator.destory(vec+i); } myallocator.deallocate(vec); maxsize *=2; vec = tmp; } } }; int main() { Vector<int> v(10); cout<<endl; return0; }
这样就解决了上面遇到的问题,在allocator 还可以带一个内存池实现
原文:https://www.cnblogs.com/lc-bk/p/13589856.html
内容总结
以上是互联网集市为您收集整理的C++ STL 容器适配器全部内容,希望文章能够帮你解决C++ STL 容器适配器所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。