注意几点:

分配内存不要使用new和delete,由于new的同一时候就把对象构造了。而我们须要的是原始内存。

所以应该使用标准库提供的allocator类来实现内存的控制。当然也能够重载operator new操作符,由于二者都是使用malloc作为底层实现,所以直接採用malloc也能够。

对象的复制必须使用系统提供的uninitialized_fill和uninitialized_copy。由于我们无法手工调用构造函数。

对于C++中的对象,除了POD之外,使用memcpy系列的函数是绝对错误的。

myvector.h

#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; class reverse_iterator
{
public:
reverse_iterator(iterator it = NULL):current_(it) {}
iterator base() const { return current_; } reverse_iterator &operator++()//前置
{
--current_;
return *this;
} reverse_iterator operator++(int)//后置
{
reverse_iterator temp(*this);
--current_;
return temp;
} reverse_iterator &operator--()
{
++current_;
return *this;
} reverse_iterator operator--(int)
{
reverse_iterator temp(*this);
++current_;
return temp;
} T &operator*()
{
iterator temp = current_;
return *--temp;
} T *operator->()
{
iterator temp = current_;
return --temp;
} friend bool operator==(const reverse_iterator &lhs,
const reverse_iterator &rhs)
{
return lhs.current_ == rhs.current_;
}
friend bool operator!=(const reverse_iterator &lhs,
const reverse_iterator &rhs)
{
return lhs.current_ != rhs.current_;
}
private:
iterator current_;
}; 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_; } reverse_iterator rbegin(){return reverse_iterator(end());}
reverse_iterator rend() {return reverse_iterator(begin());} void swap(Vector &rhs)
{
std::swap(data_, rhs.data_);
std::swap(avail_, rhs.avail_);
std::swap(limit_, rhs.limit_);
}
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 uncheckAppend(const T &);
}; template <typename T>
inline Vector<T> &Vector<T>::operator=(const Vector &rhs)
{
if(this != rhs)
{
uncreate();//释放原来的内存
create(rhs.begin(), rhs.end());
}
return *this;
} template <typename T>
inline void Vector<T>::push_back(const T &t)
{
if(avail_ == limit_)
{
grow();
}
uncheckAppend(t);
} template <typename T>
inline void Vector<T>::create()
{
//分配空的数组
data_ = avail_ = limit_ = 0;
} template <typename T>
inline 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>
inline 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>
inline 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>
inline void Vector<T>::grow()
{
//内存变为2倍
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>
inline void Vector<T>::uncheckAppend(const T &val)
{
alloc_.construct(avail_++, val);
} #endif /*VECTOR_H*/

test_main.cpp

#include "myvector.h"
#include <iostream>
#include <string>
using namespace std; void print_reverse(Vector<string> &vec)
{
cout << "reverse_iterator: " << endl;
for(Vector<string>::reverse_iterator it = vec.rbegin();
it != vec.rend();
++it)
{
cout << *it << endl;
}
cout << endl;
} void print(Vector<string> &vec)
{
cout << "iterator: " << endl;
for(Vector<string>::iterator it = vec.begin();
it != vec.end();
++it)
{
cout << *it << endl;
}
cout << endl;
} int main(int argc, const char *argv[])
{
Vector<string> vec(3, "hello"); for(Vector<string>::const_iterator it = vec.begin();
it != vec.end();
++it)
{
cout << *it << endl;
}
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; print_reverse(vec);
print(vec);
return 0;
}

转自:http://www.cnblogs.com/inevermore/p/4003710.html



C++中vector的实现的更多相关文章

  1. c++中vector的用法详解

    c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...

  2. C++的STL中vector内存分配方法的简单探索

    STL中vector什么时候会自动分配内存,又是怎么分配的呢? 环境:Linux  CentOS 5.2 1.代码 #include <vector> #include <stdio ...

  3. C++ 中vector的基本用法

    //在网上看了好久,自己总结了一下下,第一篇博客,呼呼,学到不少 基本概念 vector容器是一个模板类,可以存放任何类型的对象).vector对象可以在运行时高效地添加元素,并且vector中元素是 ...

  4. java中vector与hashtable操作详解

    众所周知,java中vector与hashtable是线程安全的,主要是java对两者的操作都加上了synchronized,也就是上锁了.因此 在vector与hashtable的操作是不会出现问题 ...

  5. [转贴]从零开始学C++之STL(二):实现一个简单容器模板类Vec(模仿VC6.0 中 vector 的实现、vector 的容量capacity 增长问题)

    首先,vector 在VC 2008 中的实现比较复杂,虽然vector 的声明跟VC6.0 是一致的,如下:  C++ Code  1 2   template < class _Ty, cl ...

  6. c++中vector等容器的实现机制

    stl容器区别: vector list deque set map-底层实现 stl容器区别: vector list deque set map (转) 在STL中基本容器有: vector.li ...

  7. 关于C++中vector和set使用sort方法进行排序

    C++中vector和set都是非常方便的容器, sort方法是algorithm头文件里的一个标准函数,能进行高效的排序,默认是按元素从小到大排序 将sort方法用到vector和set中能实现多种 ...

  8. STL中vector、list、deque和map的区别

    1 vector     向量 相当于一个数组    在内存中分配一块连续的内存空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capac ...

  9. 【转】STL中vector、list、deque和map的区别

    1.vector 向量 相当于一个数组 在内存中分配一块连续的内容空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacity()函数 ...

  10. C++中vector容器的常用操作方法实例总结

    C++中vector容器的常用操作方法实例总结 参考 1. C++中vector容器的常用操作方法实例总结: 完

随机推荐

  1. Qt在windows 平台操作保存execel的表格(通过QAxObject来操作)

    粗略操作 QT += core gui sql CONFIG += qaxcontainer greaterThan(QT_MAJOR_VERSION, 4): QT += widgets #incl ...

  2. Qt 学习 之 二进制文件读写

    在上一章中,我们介绍了有关QFile和QFileInfo两个类的使用.我们提到,QIODevice提供了read().readLine()等基本的操作.同时,Qt 还提供了更高一级的操作:用于二进制的 ...

  3. 基于visual Studio2013解决C语言竞赛题之0306分数转换

      题目 解决代码及点评 根据题目要去,我们可以通过if实现该功能,伪代码如下: if(a > 90) print 'A' else if(a>80) print 'b' else ...

  4. BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路

    1726: [Usaco2006 Nov]Roadblocks第二短路 Description 贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友.贝茜很喜欢路边的风景,不想那么快地结束她 ...

  5. Objective中的协议(Protocol)

    Objective中的协议(Protocol) 作用: 专门用来声明一大堆方法. (不能声明属性,也不能实现方法,只能用来写方法的声明). 只要某个类遵守了这个协议.就相当于拥有这个协议中的所有的方法 ...

  6. window.open 使用方法总结

    [1.最基本的弹出窗口代码] <SCRIPT LANGUAGE="javascript">  <!--  window.open ('test.html')  - ...

  7. Android之TextView------LINK的点击事件

    package com.TextHtml; import android.app.Activity; import android.content.Context; import android.os ...

  8. enum型常量

    就像结构体一样,定义一个枚举类型是不分配内存的,仅仅是定义了一个类型的名字,下面可以使用这个名字定义枚举类型的变量 枚举即将变量的值一一列举出来变量的值只限于列举出来的值得范围内 简单的应用如下 #i ...

  9. win7 ShuipFCMS 配置 及问题

    随风下载地址:http://www.shuipfcms.com/download.shtml 碰到问题: 一.mb_strlen 函数不支持   到php.ini  开启 ;extension=php ...

  10. 【转】CentOS 6.5 生产环境优化指南

    原文链接:https://www.deepwebcn.com/82.html centos6.5 CentOS 6.5 系统安装之后并不能立即投入生产环境使用,常常需要先经过我们运维人员的优化才行.优 ...