C++ 手把手教你實(shí)現(xiàn)可變長(zhǎng)的數(shù)組
— 1 —
要實(shí)現(xiàn)什么函數(shù)呢?
假設(shè)我們要實(shí)現(xiàn)一個(gè)會(huì)自動(dòng)擴(kuò)展的數(shù)組類,我們需要實(shí)現(xiàn)函數(shù)呢?先從下面 main 函數(shù)使用的功能,看看有什么函數(shù)是需要我們實(shí)現(xiàn)的。
輸出結(jié)果:
0 1 2 3 4
0 1 2 100 4
要實(shí)現(xiàn)如上的功能,要做哪些事情呢?先列出來(lái):
要用動(dòng)態(tài)分配的內(nèi)存的方式,來(lái)存放數(shù)組元素,且需要一個(gè)指針成員變量
重載賦值 = 運(yùn)算符
重載括號(hào) [] 運(yùn)算符
重載復(fù)制構(gòu)造函數(shù)
實(shí)現(xiàn) push_back 和 length 函數(shù)
— 2 —
實(shí)現(xiàn)的步驟
— —
01 構(gòu)造函數(shù)
構(gòu)造函數(shù)的目的就是初始化一個(gè)數(shù)組,代碼如下:
// 構(gòu)造函數(shù)
MyArray::MyArray(int s = 0):m_size(s)
{
// 當(dāng)初始化長(zhǎng)度為0的數(shù)組時(shí),數(shù)組指針就是空的
if(s == 0)
m_ptr = NULL;
// 當(dāng)初始化長(zhǎng)度不為0時(shí),則申請(qǐng)對(duì)應(yīng)大小的空間
else
m_ptr = new int[s];
}
— —
02 復(fù)制構(gòu)造函數(shù)
復(fù)制構(gòu)造函數(shù)目的就是產(chǎn)生一個(gè)與入?yún)?duì)象一樣的對(duì)象,但是由于 MyArray 類是有指針成員變量的,所以我們必須用深拷貝的方式來(lái)實(shí)現(xiàn)復(fù)制構(gòu)造函數(shù),如果使用默認(rèn)的復(fù)制構(gòu)造函數(shù),則會(huì)導(dǎo)致兩個(gè)對(duì)象的指針成員變量指向的地址是同一個(gè),這是非常危險(xiǎn)的。
// 復(fù)制構(gòu)造函數(shù)
MyArray::MyArray(const MyArray &a)
{
// 如果入?yún)⒌臄?shù)組對(duì)象的指針地址為空時(shí),
// 則也初始化一個(gè)空的數(shù)組
if(a.m_ptr == NULL)
{
m_ptr = NULL;
m_size = 0;
}
// 如果入?yún)⒌臄?shù)組對(duì)象有數(shù)據(jù)時(shí),則申請(qǐng)一個(gè)新的地址,
// 最后來(lái)復(fù)制入?yún)?duì)象數(shù)組對(duì)象的數(shù)據(jù)和大小。
else
{
m_ptr = new int[a.m_size];
memcpy(m_ptr, a.m_ptr, sizeof(int)*a.m_size);
m_size = a.m_size;
}
}
— —
03 析構(gòu)函數(shù)
析構(gòu)函數(shù)的目的就是釋放數(shù)組的資源,代碼如下:
// 析構(gòu)函數(shù)
MyArray::~MyArray()
{
// 如果指針地址不為空時(shí),則釋放資源
if(m_ptr)
delete [] m_ptr;
}
— —
04 重載賦值 = 運(yùn)算符函數(shù)
重載賦值 = 運(yùn)算符函數(shù)目的就是 = 號(hào)左邊對(duì)象里存放的數(shù)組,大小和內(nèi)容都和右邊的對(duì)象一樣,代碼如下:
// 重載賦值 = 運(yùn)算符函數(shù)
MyArray & MyArray::operator=(const MyArray & a)
{
if(m_ptr == a.m_ptr) // 防止a=a這樣的賦值導(dǎo)致出錯(cuò)
return *this;
if(a.m_ptr == NULL) // 如果a里面的數(shù)組是空的
{
if(m_ptr)
delete [] m_ptr; // 釋放舊數(shù)組的資源
m_ptr = NULL;
m_size = 0;
return *this;
}
// 如果原有空間足夠大,就不用分配新的空間
if(m_size < a.m_size)用分配新的空間
{
if(m_ptr)
delete [] m_ptr; // 釋放舊數(shù)組的資源
m_ptr = new int[a.m_size]; // 申請(qǐng)新的內(nèi)存地址
}
// 拷貝內(nèi)容
memcpy(m_ptr, a.m_ptr, sizeof(int)*a.m_size);
m_size = a.m_size;
return *this;
}
— —
05 重載 [] 運(yùn)算符函數(shù)
重載 [] 運(yùn)算符函數(shù)目的就是能通過(guò) [] 運(yùn)算符來(lái)獲取對(duì)應(yīng)下標(biāo)的數(shù)組值,代碼如下:
// 重載[]運(yùn)算符函數(shù)
int & MyArray::operator[](int i)
{
return m_ptr[i]; // 返回對(duì)應(yīng)下標(biāo)的數(shù)組值
}
— —
06 加入元素到數(shù)組末尾的函數(shù)
push_back 函數(shù)的目的就是把一個(gè)新的元素,加入到數(shù)組的末尾,代碼如下:
// 在數(shù)組尾部添加一個(gè)元素
void MyArray::push_back(int v)
{
if(m_ptr) // 如果數(shù)組不為空
{
// 重新分配空間
int *tmpPtr = new int[m_size + 1];
// 拷貝原數(shù)組內(nèi)容
memcpy(tmpPtr, m_ptr, sizeof(int)*m_size);
delect [] m_ptr;
m_ptr = tmpPtr;
}
else // 如果數(shù)組本來(lái)就是空的
{
m_ptr = new int[1];
}
m_ptr[m_size++] = v; //加入新的數(shù)組元素
}
— —
07 獲取數(shù)組長(zhǎng)度的函數(shù)
// 獲取數(shù)組長(zhǎng)度的函數(shù)
int MyArray:;length()
{
return m_size;
}
— 04 —
再改進(jìn)下?
int m_cout; // 數(shù)組元素的個(gè)數(shù)
int m_newNum; // 擴(kuò)容的次數(shù)
— 5 —
小結(jié)
小林coding
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!