vector

vector 的操作方式以及内部数据的内存布局与数组非常相似,因此在应用中
经常使用vector 替代数组使用,而二者最大的区别在于vector 可以灵活的进行
内存空间配置,而数组则是静态的,一旦数组定义以后则数据内存布局就确定了,
不能修改;若需要改变数组大小则只能重新定义新的数组,再把原数组中数据拷
贝到新数组(若数组为动态分配的,则须释放原数组使用内存)。vector 模板类
是动态空间分配管理,随着元素的加入,其内部机制自动扩展内存空间以容纳新
加入的元素,因此vector 对于内存空间的合理利用、使用灵活性方面优于数组,
应用程序不需要在使用前确定数组的大小,无须在开始即定义一个数组。
vector 在实现层面上,关键技术为对内存大小的控制,在重新扩展时的数据
移动,在已分配内存空间不足时,重新配置内存空间,须将原有数据拷贝到新内
存中,由此可见配置多大空间以减少内存中数据的转移拷贝对vector 实现是个考
验,vector 一般实现采用2n 的机制来分配内存,其中‘n’表示前一次分配n 个
元素占用的内存空间;由此可见vector 在内存扩展后,最后可能造成内存利用率
不高的问题,但是为了避免“配置新内存空间/数据元素拷贝/释放原内存(含原元
素的析构)”造成的巨大时间成本,目前的实现版本仍采用此策略。
实例化vector 的类型的拷贝构造函数、赋值操作符必须为public 访问属性,
vector 对象插入/删除可能会引起迭代器失效的问题,须注意。
使用
1. 定义
/*
* 描述: 定义模板类vector
* 参数:
* @_Tp 类型名称
* @_Alloc 分配器
* 注意:
* @_Alloc 参数已提供默认分配器,多数情况下使用默认分配器可满足应用
*/
template<typename _Tp, typename _Alloc = std::allocator<_Tp> > class vector;
/*
* 描述: 模板类vector 的构造函数
* 参数:
* @_Al 该vector 对象使用的分配器
* @_Count 指定构造的vector 对象中可以存储的元素数量
* @_Val 构造vector 对象元素的初始化值
* @_Right 用于构造vector 对象时复制的vector 对象
* @_First 输入迭代器,起始位置
* @_Last 输入迭代器,结束位置,不含此位置
*/
vector();
explicit vector(const Allocator& _Al);
explicit vector(size_type _Count);
vector(size_type _Count, const Type& _Val);
vector(size_type _Count, const Type& _Val, const Allocator& _Al);
vector(const vector<Type, Allocator>& _Right);
template<class InputIterator> vector(InputIterator _First, InputIterator _Last);
template<class InputIterator> vector(InputIterator _First, InputIterator _Last,
const Allocator& _Al);
/*
* 描述: 模板类vector 的析构函数
* 参数:
* 返回:
* 注意:
* 释放模板内所有元素并释放内存
*/
~vector();
使用示例:
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
#define PRINT_VECTOR(vecType, vec) \
cout << #vec << " ="; \
for (vecType::const_iterator it=vec.begin(); \
it != vec.end(); ++it) \
cout << " " << *it; \
cout << endl;
int main(int argc, char** argv)
{
{//构造函数
vector <int> v0; //构造空的int 型vector 对象
PRINT_VECTOR(vector<int>, v0);
vector <int> v1(3); //构造含有3 个元素的int 型vector 对象,元素默认值为'0'
PRINT_VECTOR(vector<int>, v1);
vector <int> v2(5, 2); //构造含有5 个元素的int 型vector 对象,元素默认值为'2'
PRINT_VECTOR(vector<int>, v2);
//构造含有3 个元素的int 型vector 对象,元素默认值为'1',
//使用与v2 同类型的分配器
vector <int> v3(3, 1, v2.get_allocator());
PRINT_VECTOR(vector<int>, v3);
//构造int 型vector 对象,并用v2 初始化
vector <int> v4( v2 );
PRINT_VECTOR(vector<int>, v4);
//构造int 型vector 对象,并用v4 的[begin()+1, begin()+3)初始化
vector <int> v5(v4.begin() + 1, v4.begin()+3);
PRINT_VECTOR(vector<int>, v5);
}
return EXIT_SUCCESS;
};
程序输出:
v0 =
v1 = 0 0 0
v2 = 2 2 2 2 2
v3 = 1 1 1
v4 = 2 2 2 2 2
v5 = 2 2
2. 添加/删除元素
/*
* 描述:在末尾插入元素
* 参数:
* 返回:
* 注意:
* 插入元素的同时,若内存不足,会重新分配,
* 并拷贝已存在元素到新内存并释放原内存
*/
void push_back(const Type& _Val);
/*
* 描述:删除末尾元素
* 参数:
* 返回:
* 注意:
* 删除元素的同时会释放所有已分配内存
*/
void pop_back();
/*
* 描述:删除所有元素
* 参数:
* 返回:
* 注意:
* 删除元素的同时会释放所有已分配内存
*/
void clear( );
使用示例:
{//添加删除元素
vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
PRINT_VECTOR(vector<int>, v);
v.pop_back();
v.pop_back();
PRINT_VECTOR(vector<int>, v);
v.clear();
PRINT_VECTOR(vector<int>, v);
}
输出:
v = 0 1 2 3
v = 0 1
v =
3. 访问元素
/*
* 描述:返回指定位置的元素的引用
* 参数:
* @_Pos 在vector 对象中的下标(位置数)
* 返回:
* 指定位置元素的索引
* 注意:
* 1.若_Pos 从0 开始计数,小于'size()',若'>= size()',则行为未定义
* 2.若_Pos 位置非法则抛出‘out_of_range’异常
*/
reference operator[](size_type _Pos);
const_reference operator[](size_type _Pos) const;
/*
* 描述:返回指定位置的元素的引用
* 参数:
* @_Pos 在vector 对象中的下标(位置数)
* 返回:
* 指定位置元素的索引
* 注意:
* 1.使用const 形式接口的返回的引用无法修改元素
* 2.若_Pos 位置非法则抛出‘out_of_range’异常
*/
reference at(size_type _Pos);
const_reference at(size_type _Pos) const;
使用示例:
{//访问元素
vector <int> v(5, 2);
cout<< "v[i] = ";
for (size_t i=0; i<v.size(); ++i)
cout << " " << v[i];
cout<<endl;
cout<< "v.at(i) = ";
for (size_t i=0; i<v.size(); ++i)
cout << " " << v.at(i);
cout<<endl;
}
输出:
v[i] = 2 2 2 2 2
v.at(i) = 2 2 2 2 2
/*
* 描述:返回指向vector 第一个元素的引用
* 参数:
* 返回:
* vector 第一个元素的引用
* 注意:
* 若vector 为空则返回值未定义(有些stl 实现版本在返回之前有检测)
*/
reference front( );
const_reference front( ) const;
/*
* 描述:返回指向vector 最后一个元素的引用
* 参数:
* 返回:
* vector 最后一个元素的引用
* 注意:
* 若vector 为空则返回值未定义(有些stl 实现版本在返回之前有检测)
*/
reference back( );
const_reference back( ) const;
使用示例:
{//访问元素
vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
if(!v.empty()) {
cout << "first element :" <<v.front() <<endl;
cout << "last element :" <<v.back() <<endl;
}
}
输出:
first element :0
last element :3
4. 大小
/*
* 描述:判断vector 是否为空
* 参数:
* 返回:
* 空true,否则false
* 注意:
*/
bool empty( ) const;
/*
* 描述:返回vector 元素个数
* 参数:
* 返回:
* 当前vector 内元素个数
* 注意:
*/
size_type size( ) const;
/*
* 描述:返回当前已经分配的内存中未使用的部分可以存放的元素个数
* 参数:
* 返回:
* 可以存放的元素个数
* 注意:
* 若vector 为空则返回值未定义(有些stl 实现版本在返回之前有检测)
*/
size_type capacity( ) const;
/*
* 描述:返回vector 对象理论上可以保存最大元素个数
* 参数:
* 返回:
* vector 对象理论上可以保存最大元素个数
* 注意:
* 计算公式:size_t(-1)/sizeof(type)
* 该接口一般而言用不到
*/
size_type max_size( ) const;
使用示例:
{//大小
vector<int> v0;
vector<int> v1(5);
cout<<"v0 empty :" << (v0.empty()? "true":"false") << ", size :" << v0.size()
<<", capacity :" << v0.capacity() << ", max_size: " << v0.max_size() << endl;
cout<<"v1 empty :" << (v1.empty()? "true":"false") << ", size :" << v1.size()
<<", capacity :" << v1.capacity()<<", max_size: " << v1.max_size() << endl;
}
输出:
v0 empty :true, size :0, capacity :0, max_size: 1073741823
v1 empty :false, size :5, capacity :5, max_size: 1073741823
5. 迭代器
模板类vector 提供4 个类型的迭代器
vector<type>::iterator //随机迭代器,双向移动,可以修改元素
vector<type>::const_iterator //随机迭代器,双向移动,不可以修改元素
vector<type>::reverse_iterator //反向随机迭代器,双向移动,可以修改元素
//反向随机迭代器,双向移动,不可以修改元素
vector<type>::const_reverse_iterator
/*
* 描述:返回指向vector 第一个元素的迭代器
* 参数:
* 返回:
* 指向翻转vector 第一个元素的迭代器
* 注意:
* 若vector 未翻转,则指向vector 最后一个元素
*/
const_iterator begin() const;
iterator begin();
/*
* 描述:返回指向vector 最后一个元素的下一个位置的迭代器
* 参数:
* 返回:
* 指向vector 最后一个元素的下一个位置的迭代器
*/
iterator end( );
const_iterator end( ) const;
/*
* 描述:返回指向翻转后vector 第一个元素的迭代器
* 参数:
* 返回:
* 指向vector 第一个元素的迭代器
* 注意:
* 若vector 为空,则指向空vector 之后的位置,因此使用此返回值时应与'end()'
* 进行比较以保证所获迭代器合法,若'begin() == end()'则vector 为空
*/
reverse_iterator rbegin( );
const_reverse_iterator rbegin( ) const;
/*
* 描述:返回指向vector 最后一个元素的下一位置的迭代器
* 参数:
* 返回:
* 指向翻转vector 最后一个元素的下一位置的迭代器
* 注意:
* 若vector 未翻转,则指向vector 第一个元素的前一位置
*/
const_reverse_iterator rend( ) const;
reverse_iterator rend( );
使用示例:
#define PRINT_VECTOR(vecType, vec) \
cout << #vec << " ="; \
for (vecType::const_iterator it=vec.begin(); \
it != vec.end(); ++it) \
cout << " " << *it; \
cout << endl;
#define PRINT_VECTOR_R(vecType, vec) \
cout << #vec << " ="; \
for (vecType::const_reverse_iterator it=vec.rbegin(); \
it != vec.rend(); ++it) \
cout << " " << *it; \
cout << endl;
{//迭代器
vector<int> v(10, 5);
PRINT_VECTOR(vector<int>, v);
vector<int>::iterator it = v.begin();
it += 3;
*it = 10;
PRINT_VECTOR(vector<int>, v);
PRINT_VECTOR_R(vector<int>, v);
vector<int>::reverse_iterator rit = v.rbegin();
rit += 5;
*rit = 15;
PRINT_VECTOR_R(vector<int>, v);
}
输出:
v = 5 5 5 5 5 5 5 5 5 5
v = 5 5 5 10 5 5 5 5 5 5
v = 5 5 5 5 5 5 10 5 5 5
v = 5 5 5 5 5 15 10 5 5 5
/*
* 描述:插入一个元素
* 插入指定数量元素
* 插入指定返回元素(从另一个vector 对象中导入)
* 参数:
* @_Where 指向待插入位置的迭代器
* @_Val 插入元素的值
* @_Count 插入元素个数
* @_First 指向待拷贝元素范围起始位置迭代器
* @_Last 指向待拷贝元素范围结束位置迭代器
* 返回:
* 返回指向新元素的迭代器
* 注意:
* 仅插入一个元素的insert 接口有返回值
* 尽量避免使用此函数,性能不佳
* 插入前vector 检测@_Where 合法性
*/
iterator insert(iterator _Where, const Type& _Val);
void insert(iterator _Where, size_type _Count, const Type& _Val);
template<class InputIterator>
void insert(iterator _Where, InputIterator _First, InputIterator _Last);
/*
* 描述:删除指定位置元素或指定范围的元素
* 参数:
* @_Where 指向待删除元素迭代器
* @_First 指向待删除元素范围起始位置迭代器
* @_Last 指向待删除元素范围结束位置迭代器
* 返回:
* 指向被删除元素的下一个位置
* 注意:
* 与'end()'比较以确定返回值是否指向vecotr 结束位置
*/
iterator erase(iterator _Where);
iterator erase(iterator _First, iterator _Last);
使用示例:
{//迭代器之添加删除元素
vector<int> v;
vector<int>::iterator it = v.begin();
it = v.insert(it, 5);
it = v.insert(it, 10);
PRINT_VECTOR(vector<int>, v);
v.insert(it, 5, 20); //注意,没有返回值
PRINT_VECTOR(vector<int>, v);
vector<int> v1(5, 1);
it = v.begin();
it += 2;
v.insert(it, v1.begin(), v1.end());
PRINT_VECTOR(vector<int>, v);
vector<int> v2;
v2.push_back(0);
v2.push_back(1);
v2.push_back(2);
v2.push_back(3);
v2.push_back(5);
it = v2.begin();
if(it != v2.end())
it = v2.erase(it);
if(it != v2.end())
cout << "it = " << *it <<endl;
PRINT_VECTOR(vector<int>, v2);
if(it != v2.end())
it = v2.erase(it, v2.end());
PRINT_VECTOR(vector<int>, v2);
}
输出:
v = 10 5
v = 20 20 20 20 20 10 5
v = 20 20 1 1 1 1 1 20 20 20 10 5
it = 1
v2 = 1 2 3 5
v2 =
6. 调整容器
/*
* 描述:设置vector 对象分配内存最小元素数量
* 参数:
* @_Count 最小存储数量
* 返回:
* 注意:
* 若设置的@_Count 比当前值小,则忽略
*/
void reserve(size_type _Count);
/*
* 描述:指定大小vector
* 参数:
* @_Newsize vector 新大小
* @_Val 元素的初始值
* 返回:
* 注意:
* 若vector 大小小于@_Newsize,则添加元素直到@_Newsize
* 若vector 大小大于@_Newsize,则删除多余的元素,直到@_Newsize
* 若vector 大小等于@_Newsize,则不操作
*/
void resize(size_type _Newsize);
void resize(size_type _Newsize, Type _Val);
使用示例:
{//调整vector
vector<int> v(10, 10);
cout <<"size :" << v.size() << ", capacity :" << v.capacity() << endl;
v.reserve(5);
cout <<"size :" << v.size() << ", capacity :" << v.capacity() << endl;
v.reserve(20);
cout <<"size :" << v.size() << ", capacity :" << v.capacity() << endl;
v.resize(5);
cout <<"size :" << v.size() << ", capacity :" << v.capacity() << endl;
v.resize(10);
cout <<"size :" << v.size() << ", capacity :" << v.capacity() << endl;
v.resize(40);
cout <<"size :" << v.size() << ", capacity :" << v.capacity() << endl;
}
输出:
size :10, capacity :10
size :10, capacity :10
size :10, capacity :20
size :5, capacity :20
size :10, capacity :20
size :40, capacity :40
7. 其他
/*
* 描述:1. 清空vector 对象自身(不释放已分配内存)
* 2. 拷贝指定数量元素到自身内存中,若内存不足则扩展
* 参数:
* @_Count 拷贝到vector 对象中元素个数
* @_Val 待拷入vector 中的元素值
* @_First 迭代器起始位置
* @_Last 迭代器结束位置
* 返回:
* void
*/
void assign(size_type _Count, const Type& _Val);
template<class InputIterator> void assign(InputIterator _First, InputIterator _Last);
/*
* 描述:返回当前vector 对象使用的分配器拷贝
* 参数:
* 返回:
* 当前vector 对象使用的分配器拷贝
* 注意:
* 通常stl 库提供的分配器已经能满足使用
* 该接口一般而言用不到
*/
Allocator get_allocator( ) const;
/*
* 描述:交换两个vector 对象
* 参数:
* @_Right 待交换的vector 对象
* @_Left 与@_Right 交换对象
* 返回:
* 注意:
* swap(_Left, _Right)接口为vector 特化的swap 算法,并非vector 成员函数
*/
void swap(vector<Type, Allocator>& _Right);
friend void swap(vector<Type, Allocator >& _Left, vector<Type, Allocator >& _Right);
使用示例:
{//其他
vector<int> v0(5, 0);
vector<int> v1(10, 1);
swap(v0, v1);
PRINT_VECTOR(vector<int>, v0);
PRINT_VECTOR(vector<int>, v1);
v1.swap(v0);
PRINT_VECTOR(vector<int>, v1);
vector<int> v3(5, 3);
vector<int> v4(10, 4);
v3.assign(v4.begin(), v4.end());
PRINT_VECTOR(vector<int>, v3);
PRINT_VECTOR(vector<int>, v4);
v4.assign(5, 0);
PRINT_VECTOR(vector<int>, v4);
}
输出:
v0 = 1 1 1 1 1 1 1 1 1 1
v1 = 0 0 0 0 0
v1 = 1 1 1 1 1 1 1 1 1 1
v3 = 4 4 4 4 4 4 4 4 4 4
v4 = 4 4 4 4 4 4 4 4 4 4
v4 = 0 0 0 0 0
作业
//instances.hpp
#ifndef __INSTACNCE_HPP__
#define __INSTACNCE_HPP__
#include <iostream>
#define PRINT_POSITION \
std::cout<<"file [" <<__FILE__<< "] line [" \
<< __LINE__<<"] function ["<<__FUNCTION__<<"]." \
<<std::endl
class ncInstancs {
public:
ncInstancs(void){
PRINT_POSITION;
}
ncInstancs(const ncInstancs &rhs) {
PRINT_POSITION;
}
ncInstancs& operator = (const ncInstancs &rhs) {
PRINT_POSITION;
return *this;
}
virtual ~ncInstancs(void) {
PRINT_POSITION;
}
private:
};
#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值