注意几点:
分配内存不要使用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容器的常用操作方法实例总结: 完
随机推荐
-
android studio集成融云 SDK 后在部分机型启动对话时崩溃
最初构建项目是 eclipse, 后来切换到 android studio来做开发. 后来多个用户反馈在android4.4机型上存在启动对话崩溃的问题.但是IOS 版工程从来没有重现. 调试报错信息 ...
-
源码安装zabbix
源码安装zabbix 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 欢迎加入:高级运维工程师之路 598432640 前言:参考网上多篇源码安装的连接,自己把安装过程丢在这 ...
-
一些JSON 教程
JSON 以下内容来自W3school. JSON:JavaScript 对象表示法(JavaScript Object Notation). JSON 是存储和交换文本信息的语法.类似 XML. ...
-
OJ题:字符串分隔
题目描述 •连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组:•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理. 输入描述: 连续输入字符串(输入2次,每个字符串长度小于10 ...
-
c语言计算过程中的过程转换
graph BT float==>double; id1[char, short]==>int; int-->unsigned unsigned-->long long--&g ...
-
mybatis(入门级项目)
框架的搭建:(两个java类,两个xml配置文件) 1.导入jar包,日志debug文件以及数据库的参数文件 2.建立持久化类(和数据库的列值相同的类) user类的一个扩展类: userQueryV ...
-
MyOD 代码实现
MyOD的代码实现 一.题目要求: 编写MyOD.java 用java MyOD XXX实现Linux下od -tx -tc XXX的功能 二.设计思路 OD命令详解: 因此,该题目所要实现的功能为以 ...
-
Oracle EBS INV更新保留
CREATE or REPPLACE PROCEDURE UpdateReservation AS -- Common Declarations l_api_version NUMBER := 1.0 ...
-
为什么JS事件函数里面都有一个参数(ev)?
因为ev是事件的参数啊!在ev中包含了事件触发时的参数,比如click事件的ev中包含着.e.pageX,e.pageY,keydown事件中包含着ev.keyCode等,在ie中,ev是全局的可以通 ...
-
一个简单的json解析器
实现一个简单地json解析器. 两部分组成,词法分析.语法分析 词法分析 package com.mahuan.json; import java.util.LinkedList; import ja ...