c++順序容器之——vector容器的實現(類模板)

看了前面的介紹今天給大家講講vector容器,首先vector就是我們數學中經常說的向量,所有vector容器也就是存放向量的容器,我們可以把他理解成數組

vector提供順序表,下標運算符[]有效。當vector的內存用盡時,我們需要自動分配更大的連續內存區,將原先的元素複製到新的內存區,然後釋放舊的內存區。內存分配是由分配子(allocator)完成.

vector支持隨機訪問迭代子(相當於指針),可以用來實現隊列,堆,棧,列表和其它複雜的結構,也就是說我們學會vector以後就可以用vector代替數組

vector的迭代子通常爲實現爲vector元素的指針。

1.系統調用

當我們想使用vector類時我們要先添加頭文件

#include<vector>

還要特別注意的是我們需要添加標準命名空間

using namespace std;

相當於一個類模板,我們使用時要先用聲明向量容器的類型構建一個容器對象

vector<int> a;//定義存放整形序列的向量容器對象a
vector<float> b;//定義存放實形序列的向量容器對象b
vector<char> c;//定義存放字符形序列的向量容器對象c

我們定義好容器對象以後就可以通過對象來調用容器的方法

vector容器的成員方法有很多,下面標紅色的是我們日常使用時常見的

assign

拭除一個向量和指定的元素複製到空的向量。

at

返回位於指定位置處的元素對向量中。

back

返回最後一個向量的元素的引用。

begin

返回一個隨機訪問迭代器向量中的第一個元素。

capacity

返回向量可能包含未分配更多存儲的元素的數目。

cbegin

返回一個隨機存取 const 迭代器向量中的第一個元素。

cend

返回一個隨機存取 const 迭代器只是向量的末尾之外的點。

crbegin

已沖銷的向量中的第一個元素中返回 const 迭代器。

crend

已沖銷的向量的末尾返回常量的迭代器。

clear

擦除向量的元素。

data

將指針返回到向量中的第一個元素。

emplace

插入到指定位置的向量構造的元素。

emplace_back

添加一個構造向量的末尾位置中的元素。

empty

測試矢量容器是空的。

end

返回一個隨機訪問迭代器指向向量的末尾。

擦除

將向量從指定位置中刪除元素或某個範圍的元素。

front

在向量中返回的第一個元素的引用。

get_allocator

返回一個對象以 allocator矢量所使用的類。

插入

插入指定位置的向量的元素的數量。

max_size

返回向量的最大長度。

pop_back

刪除末尾的向量的元素。

push_back

將元素添加到向量的末尾。

rbegin

已沖銷的向量中的第一個元素中返回迭代器。

rend

已沖銷的向量的末尾返回迭代器。

reserve

保留存儲爲矢量對象的最小長度。

resize

指定新的大小對應於向量。

shrink_to_fit

放棄過多的容量。

size

返回向量中的元素數。

2.自主實現vector容器類模板部分功能 

當我們想遍歷訪問容器中的元素時,我們需要藉助面向對象指針也就是我們經常說的迭代子(迭代器)來進行訪問,這裏不做介紹,後續會專門寫一篇關於迭代子的博客。

上述是我們採用系統調用來使用vector容器,那麼如果讓我們自己來實現vector類該怎麼實現呢?下面我給大家用代碼實現一下這個vector類模板

#include <iostream>

template<typename T>//表明類模板
class vector
{
public:
	vector()//構造函數
	{
		maxsize=2;
		arr=new T [2]();
		nowsize=0;
		printf("構造成功\n");
	}
	~vector()//析構函數
	{
		delete[] arr;
		arr=NULL;
	}
	vector(const vector&rhs)
	{
		arr=new T[rhs.maxsize]();//開闢和rhs同樣大的空間
		for(int i=0;i<maxsize;i++)//深拷貝,將數據複製過去
		{
			arr[i]=rhs.arr[i];
		}
		printf("拷貝構造成功\n");
	}
	vector& operator =(const vector& rhs)//賦值運算符重載
	{
		if(&rhs!=this)
		{
			delete[] arr;//釋放現有內存
			arr=NULL;
			arr=new T [rhs.maxsize]();//開闢和目標一樣大的內存空間
			maxsize=rhs.maxsize;//變量賦值
			nowsize=rhs.nowsize;
			for(int i=0;i<nowsize;i++)//拷貝數據
			{
				arr[i]=rhs.arr[i];
			}
		}
		return *this;
	}
	void inserthead(T val);//頭部插入
	void inserttail(T val);//尾部插入
	void insertpos(T val,int pos);//根據下標進行插入
	void deletehead();//刪除第一個元素
	void deletetail();//刪除最後一個元素
	void deletepos(int pos);//根據下標進行刪除
	T* add();//擴容
	void show()
	{
		for(int i=0;i<nowsize;i++)
		{
			printf("%d ",arr[i]);
		}
		printf("\n");
	}
private:
	T *arr;
	int nowsize;//當前存放的數據個數
	int maxsize;//最大可以存放的數據個數
};
template<typename T>
void vector<T>::inserthead(T val)
{
	if(maxsize==nowsize)//當前數據個數等於容量時說明滿了,所有擴容
	{
		add();
	}
	for(int i=nowsize;i>0;i--)
	{
		arr[i]=arr[i-1];//將所有數據向前移一位
	}
	arr[0]=val;
	nowsize++;
}
template<typename T>
void vector<T>::inserttail(T val)
{
	if(maxsize==nowsize)//當前數據個數等於容量時說明滿了,所有擴容
	{
		add();//執行擴容
	}
	arr[nowsize]=val;
	nowsize++;
}
template<typename T>
void vector<T>::insertpos(T val,int pos)
{
	if(pos>maxsize-1)
	{
		printf("位置不合法\n");
		return;
	}
	if(maxsize==nowsize)//當前數據個數等於容量時說明滿了,所有擴容
	{
		add();
	}
	for(int i=nowsize;i>pos;i--)
	{
		arr[i]=arr[i-1];//將所有數據向後移一位
	}
	arr[pos]=val;
	nowsize++;
}
template<typename T>
void vector<T>::deletehead()
{
	for(int i=0;i<nowsize-1;i++)
	{
		arr[i]=arr[i+1];//將所有數據向前移一位
	}
	nowsize--;
}
template<typename T>
void vector<T>::deletepos(int pos)
{
	if(pos>maxsize-1)
	{
		return;
	}
	for(int i=pos;i<nowsize-1;i++)
	{
		arr[i]=arr[i+1];//將所有數據向前移一位
	}
	nowsize--;
}
template<typename T>
void vector<T>::deletetail()
{
	nowsize--;
}
template<typename T>
T *vector<T>::add()
{
	maxsize=maxsize*2;
	T*brr=new T[maxsize]();
	for(int i=0;i<maxsize;i++)
	{
		brr[i]=arr[i];
	}
	delete []arr;
	arr=brr;
	return brr;
}

int main()
{
	vector<char> a;
	vector<char> b(a);
	a.inserttail(1);
	a.inserttail(3);
	a.inserttail(4);
	a.insertpos(2,1);
	b=a;
	a.show();
	b.show();
}

以上代碼就是簡單的實現了一些vector容器中比較常用的成員方法。可能會有些地方不嚴謹煩請大家指正

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章