注意几点:

分配内存不要使用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的一种实现(一)相关推荐

  1. STL vector的几种清空容器(删除)办法

    1.为什么需要主动释放vector内存 来自 <https://blog.csdn.net/hellokandy/article/details/78500067> vector其中一个特 ...

  2. STL中vector的几种初始化方式

    无参构造函数初始化 vector<char> VT; 有参数的构造函数初始化 //初始化size,但每个元素值为默认值 vector<int> abc(10); //初始化了1 ...

  3. C++11 for区间遍历:vector几种遍历方式

    近来,基本上所有现代编程语言都有一种对一个区间写for循环的便捷方式.最终,C++也有了相同的概念:你可以给循环提供一个容器,它帮你迭代. example: #include <iostream ...

  4. 谈谈两种标准库类型---string和vector

    两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...

  5. C++ 容器1 vector

    容器分类: 1.顺序容器有以下三种:可变长动态数组 vector.双端队列 deque.双向链表 list. 它们之所以被称为顺序容器,是因为元素在容器中的位置同元素的值无关,即容器不是排序的.将元素 ...

  6. C++中vector的使用

    向量std::vector是一种对象实体,能够容纳许多各种类型相同的元素,包括用户自定义的类,因此又被称为序列容器.与string相同,vector同属于STL(Standard Template L ...

  7. matlab vector用法,C++ vector 用法汇总

    标准库Vector类型 使用需要的头文件: #include Vector:Vector 是一个类模板.不是一种数据类型. Vector是一种数据类型. 一.  定义和初始化 Vectorv1;    ...

  8. Vector的使用方法和自我理解

    vector容器的作用,在于你在储存一些数的时候,可以很方便的改变他的大小,利用下标可以同数组一样轻松的遍历,却比数组强的是:vector可以删去不用的元素,已达到我们获取前一个数值: 1 基本操作( ...

  9. vector容器与iterator迭代器

    vector容器 vector是同一种类型的对象的集合,每个对象都有一个对应的整数索引值.和string对象一样,标准库负责管理存储元素的相关内存.我们把vector称为容器,是因为它可以包含其他对象 ...

最新文章

  1. php后台开发(二)Laravel框架
  2. MySQL Cluster安装
  3. UNIX环境高级编程--第七章
  4. Mysql之外连接_OUTER JOIN
  5. 【MySQL】sysbench压测服务器及结果解读
  6. ccleaner无法更新_CCleaner正在静默更新关闭自动更新的用户
  7. java 加密 数字_java 加密数字签名
  8. (六)Linux之设备驱动模型(续)
  9. C#一探究竟——枚举
  10. mysql ---- 多表设计
  11. 判断 localStorage 在不同浏览器的最大支持内存
  12. 来,亮点抢先看!网易智企机器之心即将联合发布 AI 白皮书
  13. 界面开发控件DotNetBar for WPF教程:MobileRibbon快速入门指南
  14. ps特效制作人物碎片飞溅效果
  15. 51单片机c语言编程函数,单片机C语言教程:C51函数
  16. 【目标检测-YOLO】YOLOv5-yolov5s TensorRT部署准备之ONNX导出(第一篇)
  17. 可以发布任务悬赏的app
  18. SAP快速学习小结1
  19. 修改google搜索引擎非hk方法
  20. 实录:有钱女性私生活

热门文章

  1. 用MySql的查询分析语法explain来优化查询和索引
  2. 关于 Unloading class sun.reflect.GeneratedSerial...
  3. JAX-WS开发webservice示例详解
  4. Hibernate query by Example
  5. async-await用法
  6. 知识图谱基础知识之一——人人都能理解的知识图谱
  7. window版docker安装及配置
  8. perl怎么拷贝一个文件到另一个文件夹中或者怎么拷贝文件夹到另一个文件夹
  9. Atitit ftp原理与解决方案
  10. JSP -- JSP语法