[C++]Vector源码实现
来源:互联网 发布:云计算与智慧城市 编辑:程序博客网 时间:2024/05/17 20:28
Vector源码实现
vector是STL里最常用的容器,本文尝试着用一种相对简单的方法构建一个vector实现模板,并加上std::allocator。尽可能解释其中函数的意义。
代码实现
用一个testAllocator继承allocator。此处特化int版本。
#ifndef __TEST_H__#define __TEST_H__#include <memory>#include <iostream>class testAllocator : public std::allocator<int> { public: typedef std::allocator<int> Base; // 此函数就是new功能。真正分配内存。 int * allocate(std::size_t size) { std::cout << "Test Allocator: allocate" << std::endl; return Base::allocate(size); } // delete功能。真正释放内存。 void deallocate(int * p, std::size_t size) { std::cout << "Test Allocator: deallocate" << std::endl; Base::deallocate(p, size); } // 此函数不释放内存,只赋值。 void construct(int * p, int val) { std::cout << "Test Allocator: Construct, value: " << val << std::endl; Base::construct(p, val); } // 此函数不释放内存,只把值丢去。 void destroy(int * p) { std::cout << "Test Allocator: Destroy, value: " << *p << std::endl; Base::destroy(p); }};#endif
#ifndef __VECTOR_H__#define __VECTOR_H__#define _a Alloc()#include "base.h"#include <memory>template< typename T, typename Alloc = std::allocator<T> >class myVector : public Base { public: // Constructor myVector() { _data = _a.allocate(1); _size = 0; _capacity = 1; } myVector(const std::size_t & size, const T & val, Alloc a = Alloc()) { _data = a.allocate(size); for (std::size_t i = 0; i < size; ++i) a.construct(_data + i, val); _size = _capacity = size; } template<typename InputIterator> myVector(InputIterator begin, InputIterator end, Alloc a = Alloc()) { _size = _capacity = end - begin; _data = a.allocate(_size); std::size_t cnt = 0; for (InputIterator it = begin; it != end; ++it) a.construct(_data + (cnt++), *it); } myVector(const myVector & other) { _size = other._size; _capacity = other._capacity; _data = _a.allocate(_capacity); for (std::size_t i = 0; i < _size; ++i) _a.construct(_data + i, other._data[i]); } // Destructor ~myVector() { for (std::size_t i = 0; i < _size; ++i) _a.destroy(_data + i); if (_capacity > 0) _a.deallocate(_data, _capacity); } // Copy Operator myVector & operator=(const myVector & other) { if (&other != this) { std::size_t i; for (i = 0; i < _size; ++i) _a.destroy(_data + i); if (_capacity > 0) _a.deallocate(_data, _capacity); _size = other._size; _capacity = other._capacity; _data = _a.allocate(_capacity); for (i = 0; i < _size; ++i) _a.construct(_data + i, other._data[i]); } return *this; } // Iterator typedef T * iterator; typedef const T * const_iterator; inline iterator begin() { return _data; } inline const_iterator begin() const { return _data; } inline iterator end() { return _data + _size; } inline const_iterator end() const { return _data + _size; } // Capacity inline std::size_t size() const { return _size; } void resize(const std::size_t & newSize) { std::size_t i; if (newSize <= _size) { for (i = newSize; i < _size; ++i) _a.destroy(_data + i); } else { if (newSize > _capacity) { std::size_t newCapacity = _capacity * 2; while (newSize > newCapacity) newCapacity *= 2; reserve(newCapacity); } for (i = _size; i < newSize; ++i) _a.construct(_data + i, T()); } _size = newSize; } void resize(const std::size_t & newSize, const T & val) { std::size_t i; if (newSize <= _size) { for (i = newSize; i < _size; ++i) _a.destroy(_data + i); } else { if (newSize > _capacity) { std::size_t newCapacity = _capacity * 2; while (newSize > newCapacity) newCapacity *= 2; reserve(newCapacity); } for (i = _size; i < newSize; ++i) _a.construct(_data + i, val); } _size = newSize; } inline std::size_t capacity() const { return _capacity; } inline bool empty() const { return _size == 0; } void reserve(const std::size_t & newCapacity) { if (newCapacity > _capacity) { T * temp = _a.allocate(newCapacity); for (std::size_t i = 0; i < _size; ++i) { _a.construct(temp + i, _data[i]); _a.destroy(_data + i); } _a.deallocate(_data, _capacity); _capacity = newCapacity; _data = temp; } } // Element Access inline T & operator[](const std::size_t & index) { return _data[index]; } inline const T & operator[](const std::size_t & index) const { return _data[index]; } inline T & front() { return _data[0]; } inline const T & front() const { return _data[0]; } inline T & back() { return _data[_size - 1]; } inline const T & back() const { return _data[_size - 1]; } inline T * data() { return _data; } inline const T * data() const { return _data; } // Modifiers template<typename InputIterator> void assign(InputIterator begin, InputIterator end) { std:size_t newSize = 0; InputIterator it; for (it = begin; it != end; ++it) ++newSize; if (newSize > _capacity) { std::size_t newCapacity = _capacity * 2; while (newSize > newCapacity) newCapacity *= 2; reserve(newCapacity); } std::size_t i; for (i = 0; i < _size; ++i) _a.destroy(_data + i); for (i = 0, it = begin; i < newSize; ++i, ++it) _a.construct(_data + i, *it); _size = newSize; } void assign(const std::size_t & newSize, const T & val) { if (newSize > _capacity) { std::size_t newCapacity = _capacity * 2; while (newSize > newCapacity) newCapacity *= 2; reserve(newCapacity); } std::size_t i; for (i = 0; i < _size; ++i) _a.destroy(_data + i); for (i = 0; i < newSize; ++i) _a.construct(_data + i, val); _size = newSize; } void push_back(const T & val) { if (_size >= _capacity) reserve(_capacity * 2); _a.construct(_data + (_size++), val); } void pop_back() { _a.destroy(_data + (--_size)); } void clear() { for (std::size_t i = 0; i < _size; ++i) _a.destroy(_data + i); _size = 0; } private: iterator _data; std::size_t _size, _capacity;};#endif
测试文件
#ifndef __BASE_H__#define __BASE_H__// #define vector NOT_ALLOWED#define define NOT_ALLOWEDclass Base {};#endif#include <iostream>#include "test.h"#include "base.h"#include "vector.h"int main() { typedef myVector<int, testAllocator> v; Base * test = new v; delete static_cast<v *>(test); v * p1, * p2; int t; std::cout << "Test Constructor1:" << std::endl; p1 = new v; std::cout << "Size: " << p1->size() << std::endl; delete p1; std::cout << "Test Constructor2 and operator[]:" << std::endl; p1 = new v(static_cast<std::size_t>(6), 6); std::cout << "Size: " << p1->size() << std::endl; std::cout << "Content:"; for (int i = 0; i < 2; ++i) std::cout << ' ' << (*p1)[i]; std::cout << std::endl; std::cin >> t; std::cout << "Content after change:"; (*p1)[0] = t; const v & r(*p1); for (int i = 0; i < 2; ++i) std::cout << ' ' << r[i]; std::cout << std::endl; std::cout << "Test Constructor3 and iterators, including begin(), end():" << std::endl; p2 = new v(r.begin(), r.end()); delete p1; std::cout << "Content:"; for (v::iterator it = p2->begin(); it != p2->end(); ++it) std::cout << ' ' << *it; std::cout << std::endl; std::cout << "Test Constructor4:" << std::endl; *(p2->begin()) = 0; p1 = new v(*p2); delete p2; std::cout << "Content:"; for (std::size_t i = 0; i < p1->size(); ++i) std::cout << ' ' << (*p1)[i]; std::cout << std::endl; std::cout << "Test operator=:" << std::endl; p2 = new v(static_cast<std::size_t>(8), 8); *p2 = *p1; *p2 = *p2; delete p1; std::cout << "Content:"; for (std::size_t i = 0; i < p2->size(); ++i) std::cout << ' ' << (*p2)[i]; std::cout << std::endl; std::cout << "Test resize1:" << std::endl; p2->resize(2); std::cout << "Content:"; for (std::size_t i = 0; i < p2->size(); ++i) std::cout << ' ' << (*p2)[i]; std::cout << std::endl; std::cout << "Test resize2:" << std::endl; p2->resize(8, 8); std::cout << "Content:"; for (std::size_t i = 0; i < p2->size(); ++i) std::cout << ' ' << (*p2)[i]; std::cout << std::endl; std::cout << "Test reserve and capacity:" << std::endl; p2->reserve(33); std::cout << "Capacity: " << p2->capacity() << std::endl << "Size: " << p2->size() << std::endl; p2->reserve(2); std::cout << "Capacity: " << p2->capacity() << std::endl << "Size: " << p2->size() << std::endl; std::cout << "Test clear and empty:" << std::endl; if (p2->empty()) std::cout << "True" << std::endl; else std::cout << "False" << std::endl; p2->clear(); if (p2->empty()) std::cout << "True" << std::endl; else std::cout << "False" << std::endl; std::cout << "Capcaity: " << p2->capacity() << std::endl << "Size: " << p2->size() << std::endl; int * arr = new int[5]; for (int i = 0; i < 5; ++i) arr[i] = i+1; std::cout << "Test assign:" << std::endl; p2->assign(arr, arr+5); std::cout << "Content:"; for (v::const_iterator it = p2->begin(); it != p2->end(); ++it) std::cout << ' ' << *it; std::cout << std::endl << "Size: " << p2->size() << std::endl << "Capacity: " << p2->capacity() << std::endl; delete [] arr; delete p2; return 0;}
0 0
- [C++]Vector源码实现
- C语言实现 vector
- c实现vector
- c++vector简单实现
- 【C++】实现容器Vector
- c++:模拟实现vector
- vector的实现【C++】
- vector容器部分源码实现
- 数据结构-Vector实现(C++)
- 【STL C++】简单实现vector
- C++vector实现约瑟夫环
- c语言实现vector实例
- 【c++】模板实现动态Vector
- c++stl vector源码简析
- c++stl vector源码简析
- STL的vector的源码实现
- stl源码剖析 第四章vector实现
- vector源码
- Angularjs之ngModel中的值验证绑定
- adnroid textview设置文字横向自动滚动(跑马灯效果)
- eclipse自动补全的设置
- webview的两个方法:setWebChromeClient和setWebClient
- css的一些总结和注意点
- [C++]Vector源码实现
- 复杂度为O(n)的环路分离算法
- SynchronizedMap和ConcurrentHashMap的深入分析
- Android系统中Bitmap是否有调用recycle方法的必要性
- IOS开发报错- objc_msgSend()报错Too many arguments to function call ,expected 0,have3
- jQuery Mobile 导航栏和布局
- Spring项目用junit 时出现org.junit.runners.BlockJUnit4ClassRunner cannot be resolved
- C语言深度剖析——读书笔记
- 防止Button的频繁点击