注意几点:

分配内存不要使用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_ = ;
} 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_ = ;
} template <typename T>
void Vector<T>::grow()
{
//内存变为两倍
size_type new_size = std::max( * (limit_ - data_), std::ptrdiff_t());
//分配原始内存
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(, "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 ;
}

Vector的一种实现(一)的更多相关文章

  1. c++中vector向量几种情况的总结(向量指针,指针的向量)

    1.标准库vector类型 vector 是同一种类型的对象的集合.每一个对象都有一个相应的整数索引值.标准库将负责管理与存储元素相关的内存.我们把 vector 称为容器,是由于它能够包括其它对象. ...

  2. 论C++11 中vector的N种遍历方法

    随着C++11标准的出现,C++标准添加了许多有用的特性,C++代码的写法也有比较多的变化. vector是经常要使用到的std组件,对于vector的遍历,本文罗列了若干种写法. (注:本文中代码为 ...

  3. vector的几种初始化和遍历

    随着C++11标准的出现,vector出现了新的初始化和遍历用法,但是vs2010和较高版本并没有能完全支持C++11标准,所以我就将它的所有的用法归纳了一下. vector的初始化 vector基本 ...

  4. Vector的一种实现(二)

      增加了逆置迭代器的实现 以及swap功能   完整代码如下: #ifndef VECTOR_H_ #define VECTOR_H_ #include <stddef.h> #incl ...

  5. C++11中vector的几种遍历方法

    假设有这样的一个vector: vector<int> line={1,2,3,4,5,6,7,8,9}; 需要输出vector里的每个元素,主函数如下: void showvec(con ...

  6. C++stl中vector的几种常用构造方法

    #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #i ...

  7. vector的几种初始化及赋值方式

    转自https://www.cnblogs.com/quyc/p/12857054.html (1)不带参数的构造函数初始化 //初始化一个size为0的vector vector<int> ...

  8. C++ vector清空元素的三种方法

    #include <iostream> #include <vector> using namespace std; //STL vector的几种清空容器(删除)办法 voi ...

  9. 【c++基础】vector初始化的几种方式

    前言 STL中的vector有几种初始化方式,根据不同的需求选择合适的初始化方式. 源码 // constructing vectors #include <iostream> #incl ...

随机推荐

  1. bzoj4059 [Cerc2012]Non-boring sequences

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4059 [题解] 考虑分治.定义过程solve(l,r)为判断全在[l,r]范围内的所有连续子 ...

  2. UVA 10229 Modular Fibonacci

    斐波那契取MOD.利用矩阵快速幂取模 http://www.cnblogs.com/Commence/p/3976132.html 代码: #include <map> #include ...

  3. MyBatis报错 Parameter '0' not found. Available parameters are [arg1, arg0, param1, param2]

    修改 <update id="updateStatusById" parameterType="java.lang.Integer"> update ...

  4. 51nod 1101 换零钱 【完全背包变形/无限件可取】

    1101 换零钱  基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 N元钱换为零钱,有多少不同的换法?币值包括1 2 5分,1 2 5角,1 2 5 ...

  5. Python的程序结构[1] -> 方法/Method[0] -> 类实例方法、私有方法和抽象方法

    类实例方法.私有方法和抽象方法 Python中最常用的就是类实例方法,类似于属性中的类实例属性,同时,也存在与私有属性类似方法,即私有方法,下面介绍这两种常见的方法,以及一种特殊意义的类实例方法 -- ...

  6. HDU 2586 How far away? LCA 转化成RMQ

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 [题意] 给出一个N 个和N-1条边的连通图,询问任意两点间的距离.N<=40000 . [分 ...

  7. centos下crontab的使用

    1.作用 使用crontab命令可以修改crontab配置文件,然后该配置由cron公用程序在适当的时间执行,该命令使用权限是所有用户. 2.格式 crontab [-u user] {-l | -r ...

  8. iOS开发 Swift开发数独游戏(四) 游戏界面的界面与逻辑

    一.游戏界面涉及到的功能点 1)数独格子的建模 (1)绘制数独格子要考虑到标记功能 所以要在每个格子内预先塞入9个标记数字,仅数独格子算下来就有9*9*9=729个格子且存在大量嵌套(这导致我在操作S ...

  9. Android入门之文件系统操作(一)简单的文件浏览器 (转)

    Android入门之文件系统操作(一)简单的文件浏览器 (转)        import java.io.File; import java.util.*; import android.app.A ...

  10. 关于spring.net的面向切面编程 (Aspect Oriented Programming with Spring.NET)-简介

    本文翻译自Spring.NET官方文档Version 1.3.2. 受限于个人知识水平,有些地方翻译可能不准确,但是我还是希望我的这些微薄的努力能为他人提供帮助. 侵删. 简介 Aspect-Orie ...