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容器的常用操作方法实例总结: 完
随机推荐
- SkipFish
https://zmap.io/ http://code.google.com/p/skipfish/wiki/SkipfishDoc#How_to_run_the_scanner?
- Android项目增加混淆
主要介绍向Android项目中添加混淆功能 增加混淆的原因 提高安全性,增加反编译的难度 减少APK的文件大小 实践 混淆的配置 一般情况下,app module 的 build.gradle 文件默 ...
- POJ 1741 Tree【Tree,点分治】
树上的算法真的很有意思……哈哈. 给一棵边带权树,问两点之间的距离小于等于K的点对有多少个. 将无根树转化成有根树进行观察.满足条件的点对有两种情况:两个点的路径横跨树根,两个点位于同一颗子树中. 如 ...
- Average(模拟)
Average Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Tota ...
- 技术贴:解码时AVC1和H264的差别
我一直疑问为什么有些视频解码时显示格式是:H264,大部分又是:AVC1 我在搜索编程资料时在微软的msdn上发现的: 原文:http://msdn.microsoft.com/en-us/libra ...
- 乐视(letv)网tkey破解
乐视网tkey算法频繁变动,怎样才干获得她算法的源代码,以不变应万变? 本文仅仅用于技术交流.提醒各位尊重站点版权,请勿用于其他用途,否则后果自负! 使用软件 Adobe Flash Builder ...
- C++赋值函数详解
赋值函数 每个类只有一个赋值函数 由于并非所有的对象都会使用拷贝构造函数和赋值函数,程序员可能对这两个函数有些轻视. 1,如果不主动编写拷贝构造函数和赋值函数,编译器将 ...
- ThinkPHP - 自动创建 + 自动验证 + 自动完成
自动创建:创建数据模型. $User->create(); 自动验证:验证提交的表单数据. protected $_validate = array( array('verify','requi ...
- (Problem 1)Multiples of 3 and 5
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The ...
- js中innerHTML与innerText的用法与区别
用法: <div id="test"> <span style="color:red">test1</span> te ...