三根指標建立動態陣列

2021-10-21 20:09:43 字數 3600 閱讀 5450

在物件導向程式設計這門課上,老師給我們布置了乙個任務,要我們完成類似於stl中的vector容器,說白了就是建立乙個動態陣列。

建立乙個的方法可以說有很多,其中常見的有利用乙個陣列指標+陣列大小的類建立,但是該種會造成插入與刪除極其不方便的問題(一般來說,用這種方式建立的陣列完成刪除、增添等操作的時候都要重新申請乙個陣列然後賦值的方式)。於是可以想出另一種方式:利用乙個陣列指標+陣列當前的大小+陣列最大容量的方式建立類。 

class myarray_

;

其中my_arrary陣列指標不用解釋了吧,m_max_size就是陣列的最大容量,在建構函式中會將它初始化為使用者給出的大小的2倍(即建構函式中形參size的2倍),目的很簡單,就是面對增加操作時,盡量少的重新設定指標申請新空間然後再賦值。有了m_max_size的話,只要當前陣列的數量(m_pre_size)不超過m_max_size,就不用上述操作,而是可以簡單地的my_array(m_ptr_size) = num;m_pre_size ++;就可以了。

以下是簡單的實現,有問題請指出。

myarray_::myarray_()

myarray_::myarray_(int size)

void myarray_::push_back(int num)

else //需要擴容的情況,需要重新申請位址

m_pre_size++;

new_my_array[m_pre_size - 1] = num;

my_array = new_my_array; }}

void myarray_::delet(int pos)

//不為空的情況

int* new_my_arrary = new int[m_max_size]; //重新申請位址

for (int i = 0; i < pos ; i++)

for (int i = pos; i < m_pre_size - 1; i++) //拷貝剩下的元素,正好漏下乙個刪除元素沒拷貝

m_pre_size--;

my_array = new_my_arrary; //別忘了把刪除後的位址重新賦值回去

}void myarray_::print() //debug函式

cout << endl;

}

這裡的刪除操作只是其中一種簡單的實現,還可以利用swap函式對陣列中要刪除元素的後面所有元素進行交換,同樣可以完成刪除操作,相比較**給出的方法,此種方法時間複雜度會大大減小,尤其是當刪除的元素的位置靠近陣列末尾時。

當然上述方法好像並不滿足題目上要求的利用三個指標的方式實現vector容器。但是不慌,有了剛才的思路,可以想到建立出三個指標:指向陣列首位址的指標(陣列名)+指向當前最後乙個元素下一位置的指標 + 當前陣列最大容量下一位置的指標,就可以完成和上面核心思想一樣的操作了。三根指標的示意圖如圖所示:(利用的是c++風格的指標示意,有點像c++風格迭代器的樣式,即指標不直接指向任何乙個元素,相信大家應該都懂……)

理解清楚了這個,剩下的就不難了。利用c++指標的特性,剛才那個類的m_pre_size就是present-begin,而m_max_size就是end-begin!這不是我瞎說的,大家可以隨意建立乙個動態陣列試一下,指標相減就是他們的位置差。所以直接可以對剛才那個類在進行一次包裝就能完成該任務了!

直接看看類的屬性和行為吧:

template class myvector

;

template myvector::myvector()

template myvector::myvector(int size)

template//copy ctor,深拷貝

myvector::myvector(myvector& obj)

}template myvector::~myvector()

建構函式裡面的拷貝建構函式不能直接利用系統預設的,實際上那只是淺拷貝,在析構的時候會造成重複刪除的問題。所以要我們自己寫copy ctor,自己寫的才是深拷貝。(深拷貝和淺拷貝這裡就不多說了,畢竟那麼多大牛已經講得清清楚楚了)

還有就是令人頭疼的析構函式……(這個東西很重要)我嘗試過delete begin,present,end;begin = present = end = null,但是編譯器總是報錯。後來才想到,因為present和end指標都是在begin建立出來的記憶體之上的,所以我原來的那種寫法會造成指標的重複刪除,才導致的編譯不通過,所以只需要delete掉bigin指標就行了。為了防止野指標的產生,同時也要對所以的三個指標都要 = null操作(實際上,如果只刪除掉begin指標,而不對present和end進行任何處理的話,就一定會造成野指標的出現:利用解引用的方式(*present與*end)訪問該指標指向的值,會出現意料之外的數字……)。

剩下的就是一下成員函式的實現了,沒有什麼需要注意的事情,就是考驗對指標是否能靈活應用。(比如present- begin就是當前陣列中儲存數字的個數,*begin就能訪問到第乙個元素,*(begin + 1)就能訪問到第二個元素……)

template void myvector::push_back(t i)

else

end = temp + (end - begin) * 2;

begin = temp;

delete temp;

temp = null;

*present = i;

present++; }}

template void myvector::delet(int pos) //i從0開始索引

t* new_begin = new t[end - begin];

for (int i = 0; i < pos; i++)

for (int i = pos; i < (end - begin - 1); i++)

end = new_begin + (end - begin);

present = new_begin + (present - begin) - 1;

begin = new_begin; }

template void myvector::print()

cout << endl;

}

c++中的指標系統雖然複雜但是很有趣,並且最能接近**編譯的真實情況。得益於完備的c++指標體系(之所以稱為體系是因為指標真的有好多過載操作啊),使我們較為簡單的完成了該題目。希望在以後的學習生活中能夠勤於思考,敢於試錯,知其然更要知其所以然,發揮出自身優勢。

最後想以一句話來結尾:千里之行,始於足下。事在人為!

指標 動態陣列的建立

1.1 malloc 陣列的建立 int p int malloc sizeof int n 陣列的刪除 free p 1.2 new 陣列的建立 int p new int n 陣列的刪除 delete p 2.1 malloc 陣列的建立 int p int malloc sizeof int ...

指標六 動態建立二維陣列

有時,我們在使用陣列時,一開始並不知道資料多少,建立多大的空間比較好,這樣的話使用動態建立陣列方便而且使用。本文章主要講述的是動態二維陣列的建立 demo 使用二級指標動態申請二維陣列 include include int main void int i,j,m,n unsigned short ...

建立動態陣列

1.動態陣列的定義 int pia new int 10 2.初始化動態的陣列 string psa new string 10 int pia new int 10 3.const物件的動態陣列 4.允許動態分配空陣列 size t n get size int p new int n 如果上述的...