Vector的一种实现(一)
注意几点:
分配内存不要使用new和delete,因为new的同时就把对象构造了,而我们需要的是原始内存。
所以应该使用标准库提供的allocator类来实现内存的控制。当然也可以重载operator new操作符,因为二者都是使用malloc作为底层实现,所以直接采用malloc也可以。
对象的复制必须使用系统提供的uninitialized_fill和uninitialized_copy,因为我们无法手工调用构造函数。
对于C++中的对象,除了POD之外,使用memcpy系列的函数是绝对错误的。
代码如下:
#ifndef VECTOR_H_ #define VECTOR_H_#include <stddef.h> #include <algorithm> #include <memory>template <typename T> class Vector { public:typedef T *iterator;typedef const T *const_iterator;typedef size_t size_type;typedef T value_type;Vector() { create(); }explicit Vector(size_type n, const T &t = T()) { create(n, t); }Vector(const Vector &v) { create(v.begin(), v.end()); }~Vector() { uncreate(); }Vector &operator=(const Vector &other);T &operator[] (size_type i) { return data_[i]; }const T &operator[] (size_type i) const { return data_[i]; }void push_back(const T &t);size_type size() const { return avail_ - data_; }size_type capacity() const { return limit_ - data_; }iterator begin() { return data_; }const_iterator begin() const { return data_; }iterator end() { return avail_; }const_iterator end() const { return avail_; }private:iterator data_; //首元素iterator avail_; //末尾元素的下一个位置iterator limit_; //内存的后面一个位置 std::allocator<T> alloc_; //内存分配器void create();void create(size_type, const T &);void create(const_iterator, const_iterator);void uncreate();void grow();void uncheckedAppend(const T &); };template <typename T> Vector<T> &Vector<T>::operator=(const Vector &rhs) {if(this != &rhs){uncreate(); //释放原来的内存 create(rhs.begin(), rhs.end());}return *this; }template <typename T> void Vector<T>::push_back(const T &t) {if(avail_ == limit_){grow();}uncheckedAppend(t); }template <typename T> void Vector<T>::create() {//分配空的数组data_ = avail_ = limit_ = 0; }template <typename T> void Vector<T>::create(size_type n, const T &val) {//分配原始内存data_ = alloc_.allocate(n);limit_ = avail_ = data_ + n;//向原始内存填充元素 std::uninitialized_fill(data_, limit_, val); }template <typename T> void Vector<T>::create(const_iterator i, const_iterator j) {data_ = alloc_.allocate(j-i);limit_ = avail_ = std::uninitialized_copy(i, j, data_); }template <typename T> void Vector<T>::uncreate() {if(data_){//逐个进行析构iterator it = avail_;while(it != data_){alloc_.destroy(--it);}//真正的释放内存alloc_.deallocate(data_, limit_ - data_);}//重置指针data_ = limit_ = avail_ = 0; }template <typename T> void Vector<T>::grow() {//内存变为两倍size_type new_size = std::max(2 * (limit_ - data_), std::ptrdiff_t(1));//分配原始内存iterator new_data = alloc_.allocate(new_size);//复制元素iterator new_avail = std::uninitialized_copy(data_, avail_, new_data);uncreate(); //释放以前的内存,以及析构元素 data_ = new_data;avail_ = new_avail;limit_ = data_ + new_size; }template <typename T> void Vector<T>::uncheckedAppend(const T &val) {alloc_.construct(avail_++, val); }#endif /* VECTOR_H_ */
测试代码如下:
#include "Vector.hpp" #include <iostream> #include <string> using namespace std;int main(int argc, char const *argv[]) {Vector<string> vec(3, "hello");for(Vector<string>::const_iterator it = vec.begin();it != vec.end();++it){cout << *it << " ";}cout << endl;cout << "size = " << vec.size() << endl;cout << "capacity = " << vec.capacity() << endl;vec.push_back("foo");vec.push_back("bar");cout << "size = " << vec.size() << endl;cout << "capacity = " << vec.capacity() << endl;return 0; }
转载于:https://www.cnblogs.com/inevermore/p/3998981.html
Vector的一种实现(一)相关推荐
- STL vector的几种清空容器(删除)办法
1.为什么需要主动释放vector内存 来自 <https://blog.csdn.net/hellokandy/article/details/78500067> vector其中一个特 ...
- STL中vector的几种初始化方式
无参构造函数初始化 vector<char> VT; 有参数的构造函数初始化 //初始化size,但每个元素值为默认值 vector<int> abc(10); //初始化了1 ...
- C++11 for区间遍历:vector几种遍历方式
近来,基本上所有现代编程语言都有一种对一个区间写for循环的便捷方式.最终,C++也有了相同的概念:你可以给循环提供一个容器,它帮你迭代. example: #include <iostream ...
- 谈谈两种标准库类型---string和vector
两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...
- C++ 容器1 vector
容器分类: 1.顺序容器有以下三种:可变长动态数组 vector.双端队列 deque.双向链表 list. 它们之所以被称为顺序容器,是因为元素在容器中的位置同元素的值无关,即容器不是排序的.将元素 ...
- C++中vector的使用
向量std::vector是一种对象实体,能够容纳许多各种类型相同的元素,包括用户自定义的类,因此又被称为序列容器.与string相同,vector同属于STL(Standard Template L ...
- matlab vector用法,C++ vector 用法汇总
标准库Vector类型 使用需要的头文件: #include Vector:Vector 是一个类模板.不是一种数据类型. Vector是一种数据类型. 一. 定义和初始化 Vectorv1; ...
- Vector的使用方法和自我理解
vector容器的作用,在于你在储存一些数的时候,可以很方便的改变他的大小,利用下标可以同数组一样轻松的遍历,却比数组强的是:vector可以删去不用的元素,已达到我们获取前一个数值: 1 基本操作( ...
- vector容器与iterator迭代器
vector容器 vector是同一种类型的对象的集合,每个对象都有一个对应的整数索引值.和string对象一样,标准库负责管理存储元素的相关内存.我们把vector称为容器,是因为它可以包含其他对象 ...
最新文章
- php后台开发(二)Laravel框架
- MySQL Cluster安装
- UNIX环境高级编程--第七章
- Mysql之外连接_OUTER JOIN
- 【MySQL】sysbench压测服务器及结果解读
- ccleaner无法更新_CCleaner正在静默更新关闭自动更新的用户
- java 加密 数字_java 加密数字签名
- (六)Linux之设备驱动模型(续)
- C#一探究竟——枚举
- mysql ---- 多表设计
- 判断 localStorage 在不同浏览器的最大支持内存
- 来,亮点抢先看!网易智企机器之心即将联合发布 AI 白皮书
- 界面开发控件DotNetBar for WPF教程:MobileRibbon快速入门指南
- ps特效制作人物碎片飞溅效果
- 51单片机c语言编程函数,单片机C语言教程:C51函数
- 【目标检测-YOLO】YOLOv5-yolov5s TensorRT部署准备之ONNX导出(第一篇)
- 可以发布任务悬赏的app
- SAP快速学习小结1
- 修改google搜索引擎非hk方法
- 实录:有钱女性私生活