C++中vector的实现
注意几点:
分配内存不要使用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的实现的更多相关文章
- c++中vector的用法详解
c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...
- C++的STL中vector内存分配方法的简单探索
STL中vector什么时候会自动分配内存,又是怎么分配的呢? 环境:Linux CentOS 5.2 1.代码 #include <vector> #include <stdio ...
- C++ 中vector的基本用法
//在网上看了好久,自己总结了一下下,第一篇博客,呼呼,学到不少 基本概念 vector容器是一个模板类,可以存放任何类型的对象).vector对象可以在运行时高效地添加元素,并且vector中元素是 ...
- java中vector与hashtable操作详解
众所周知,java中vector与hashtable是线程安全的,主要是java对两者的操作都加上了synchronized,也就是上锁了.因此 在vector与hashtable的操作是不会出现问题 ...
- [转贴]从零开始学C++之STL(二):实现一个简单容器模板类Vec(模仿VC6.0 中 vector 的实现、vector 的容量capacity 增长问题)
首先,vector 在VC 2008 中的实现比较复杂,虽然vector 的声明跟VC6.0 是一致的,如下: C++ Code 1 2 template < class _Ty, cl ...
- c++中vector等容器的实现机制
stl容器区别: vector list deque set map-底层实现 stl容器区别: vector list deque set map (转) 在STL中基本容器有: vector.li ...
- 关于C++中vector和set使用sort方法进行排序
C++中vector和set都是非常方便的容器, sort方法是algorithm头文件里的一个标准函数,能进行高效的排序,默认是按元素从小到大排序 将sort方法用到vector和set中能实现多种 ...
- STL中vector、list、deque和map的区别
1 vector 向量 相当于一个数组 在内存中分配一块连续的内存空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capac ...
- 【转】STL中vector、list、deque和map的区别
1.vector 向量 相当于一个数组 在内存中分配一块连续的内容空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacity()函数 ...
- C++中vector容器的常用操作方法实例总结
C++中vector容器的常用操作方法实例总结 参考 1. C++中vector容器的常用操作方法实例总结: 完
随机推荐
- Java chapter04-1
public class CPU { int speed; //获得speed的值 public void setSpeed(int m){ speed = m; } //返回speed的值 publ ...
- UIColor深入研究(CGColor,CIColor)
由于跟人比较喜欢研究关于图层与动画方面的技术,正打算看看别人写的好东西,就遇到了好几个问题, 第一:UIClor类方法的使用 就是关于UIColor的使用,记得之前开发中我们使用的都是UIColor后 ...
- 【转】 /etc/fstab功能详解
[转] /etc/fstab功能详解 最近去客户现场时,遇到 了一个关于挂载文件/etc/fstab文件的问题,就写了一下/etc/fstab文件的作用一个文件中各个参数的含义.供大家参考有不正确的地 ...
- 计算闰年_winform
新建窗体应用程序(如下),新建控件label1,label2,label3,textBOX1,button1,button2 label1的Text属性改为“计算闰年演示” label2的Text属性 ...
- 10_9 java笔记
java中所有的关键字都是小写的注意main虽然被编译器识别,但是它并不是关键字包:(名字小写) 单级包:liyi 多级包:cn.itcast path 和classpath的区别:path环境变量里 ...
- BZOJ 1978: [BeiJing2010]取数游戏 game( dp )
dp(x)表示前x个的最大值, Max(x)表示含有因数x的dp最大值. 然后对第x个数a[x], 分解质因数然后dp(x) = max{Max(t)} + 1, t是x的因数且t>=L -- ...
- Android线程和handler
根据视频仿照着写了个demo: package com.wyl.wylthreadtest; import android.graphics.Color; import android.os.Bund ...
- Ural 1149 - Sinus Dances
Let An = sin(1–sin(2+sin(3–sin(4+…sin(n))…)Let Sn = (…(A1+n)A2+n–1)A3+…+2)An+1For given N print SN I ...
- C语言之基本算法09—各位全是a的数列之和
/* ================================================================== 题目:数列为a,aa,aaa,--.求a+aa+aaa+-- ...
- Sqrt(x) 牛顿迭代法
为了实现sqrt(x),可以将问题看成是求解\(x^2-y=0\) ,即sqrt(y)=x: 牛顿法是求解方程的近似方法,给定初始点\((x0,f(x0))\),迭代公式为: #include < ...