陣列的新玩法,建立陣列類。
c語言中的陣列不好用嗎?為什麼需要陣列類?仔細思考一下,原生陣列有缺點嗎?額,還真有!在使用陣列的時候,使用者想要獲取陣列的長度是比較麻煩,如果不清楚函式引數傳遞的規則,使用函式來求陣列長度,得到的必然是錯誤的結果。比如:
#include
using
namespace std;
intarray_length
(int a)
intmain
(int argc,
const
char
* ar**)
; cout <<
array_length
(a)<< endl;
// 結果是1
return0;
}
輸出奇怪,原因何在?為什麼傳了個陣列進函式就不對了呢?這就要講講函式引數傳遞的原理了,一般的引數都是直接在記憶體裡拷貝乙份出來,然後在函式體裡面隨意使用,但是使用陣列作為形參就特別一點了,編譯器會化繁為簡,直接將陣列轉換為指標進行傳遞。是不是沒有辦法求陣列的長度了呢?no,來看看強大的巨集定義:
#include
using
namespace std;
#define array_length(a) sizeof(a)/sizeof(*a)
intmain
(int argc,
const
char
* ar**)
; cout <<
array_length
(a)<< endl;
return0;
}
巨集定義確實強大的一筆。但是巨集定義是由預處理器處理的,編譯器並不知道巨集的存在,使用不當容易出錯。
講了一大堆原生陣列的東西,現在直奔主題,陣列類,用物件導向的思想實現的乙個類。提供各種方法使得陣列類擁有原生陣列的各種操作。比如陣列操作符的使用,這就很方便了,並且還能對下標引數進行越界檢查,如果引數異常則預設使用 throw(0) 拋乙個0,(補個小知識點:編譯器對原生陣列下標越界是攤手的,但程式可能會崩掉)。然後就是提供設定目標元素、獲取目標元素以及獲取陣列長度的方法。
話不多說,上**:
#ifndef array_h
#define array_h
template
<
typename t>
// 使用模板,接收任意型別的引數
class
array
else
return ret;
}bool
get(
int i,
const t& value)
const
else
return ret;}
t get
(int i)
const
return ret;
} t&
operator
(int i)
else}
t operator
(int i)
const
else
} t*
array()
// 返回陣列首元素位址,可用於排序等操作
virtual
intlength()
const=0
;// 宣告為純虛函式,作為基類只用於被繼承而不能實列化};
#endif
陣列基類就建立完成了,對比著原生陣列來做思考,我們需要怎麼樣的陣列類呢?原生陣列在定義的時候就已經確定長度,之後便再也無法修改,這是不是有點不方便呢,我們就對這做一點點的改進,提供兩個陣列類,乙個是固定大小的,另乙個則是可以動態決定大小的。這樣選擇可就豐富了!先來個簡單的靜態陣列類壓壓驚。
#ifndef staticarray_h
#define staticarray_h
#include
"array.h"
template
<
typename t,
int n>
// 使用模板
class
staticarray
:public array
staticarray
(const staticarray
& obj)
// 拷貝建構函式,使用自身的空間,但是用別人的內容}
staticarray
&operator=(
const staticarray
& obj)}}
intlength()
const};
#endif
靜態陣列類就完成了哦,馬上來使用一下!
完成了靜態陣列類啦,正所謂高下相盈,那就一鼓作氣實現動態陣列類吧。首先分析,何為動態,如何實現動態,其實作為一名學過c語言的人兒,心照不宣地想到堆空間的動態申請和動態釋放。沒錯,動態陣列類的實現要點就是從堆空間申請一片記憶體空間,當動態陣列類物件覺得空間太小了,已經不夠用了,那就重新申請一塊大得堆空間記憶體,(!!!注意:必須釋放之前的堆空間,記憶體洩漏極其危險),如果覺得太大。。。。也一樣的操作。好了,上**:
#ifndef dynamicarray_h
#define dynamicarray_h
#include
"array.h"
template
<
typename t>
class
dynamicarray
:public array
else
}dynamicarray
(const dynamicarray
& obj)
// 拷貝建構函式}}
dynamicarray
&operator=(
const dynamicarray
& obj)
}
obj.m_array =
null
;delete
tem;}}
void
resize
(int newlen)
// 實現動態陣列的關鍵函式
}else
delete
tem;
// 很重要,把之前的記憶體空間釋放
}int
length()
const};
#endif
動態陣列的玩法如下:
#include
#include
"dynamicarray.h"
using
namespace std;
intmain
(int argc,
const
char
* ar**)
cout << endl;
for(
int i =
0; i <5;
++ i)
da.resize(10
);// 擴大一倍
cout <<
"second length : "
<< da.
length()
<< endl;
for(
int i =
0; i <10;
++ i)
cout << endl;
for(
int i =
0; i < da.
length()
;++ i)
return0;
}
僅僅是一維陣列好像不夠酷!認真的?那就實現二維陣列咯,溫故知新,先回想一下c語言中的二維陣列,形式確實是二維陣列,但本質還是一維陣列,只不過變成了陣列的陣列,二維陣列在記憶體的排布是按照乙個個大小相同陣列順序儲存,所以利用陣列類來實現二維陣列就不難了,上**:
#include
#include
"dynamicarray.h"
using
namespace std;
intmain
(int argc,
const
char
* ar**)
for(
int i =
0; i < dda.
length()
;++ i)
cout << endl;}
cout << endl;
for(
int i =
0; i < dda.
length()
;++ i)
}return0;
}
二維陣列的輸出還是挺酷的嘛。
六 陣列類的建立
順序儲存結構的線性表存在著兩個方面的問題 功能方面 陣列操作符的過載,線性表有可能被誤用為陣列使用 效率方面 在一些場合中,效率上是有隱患的 解決方案 當前的庫中沒有可以代替原生陣列的實現,所以有可能會被誤用,需要建立乙個陣列類代替原生陣列。需求分析 建立陣列類代替原生陣列的使用 array設計要點...
C Array類 建立陣列
除了使用c 語法 建立陣列之外,還可以使用靜態方法 createinstance 建立陣列。舉個例子 array intarray1 array.createinstance typeof int 5 for int i 0 i 5 i for int i 0 i 5 i 在這個例子中,演示了如何建...
C Array類 建立陣列
c 中建立陣列,常見的例如 int array new int 5 除了使用c 語法 建立陣列之外,還可以使用靜態方法createinstance 建立陣列。array test array.createinstance typeof int 5 for int i 0 i test length ...