我們先來讀一小段代碼吧,進而引出幾個概念:
template <class T>
class PFArray
{
public:
PFArray();
PFArray(int capacityValue );
PFArray(const PFArray& copyArray);
void addElement(int element);
bool isfull() const {return (used==capacity);}
int getCapacity() const {return capacity;}
int getUsedSize() const {return used;}
void emptyArray() {used = 0;}
void print() const;
bool isEqual(const PFArray & array1, const PFArray & arry2);
//重載指派操作
PFArray & operator = (const PFArray &rightSide);
private:
T * a;
int capacity;
int used;
}
1、常引用調用參數 ,常類成員函數
首先,C++的一個優勢,引用調用方式,比傳值調用 方式效率高。
(1)傳值調用時形參是一個局部變量,并使用實參來初始化。那麼在函數被調用時,程式中相當于有兩個實參的副本。而引用則是實參的一個别名,是以程式中隻有實參一個副本。這種情況對于簡單的資料類型,效率上的差別可以忽略不計。但是對于結構或類型來說,則不可小視了。
(2)注意傳值調用時形參是一個局部變量的問題,在考慮傳參方式時要慎重。
(3)如果在引用調用時,函數不需要改變參數的值,那麼可以對不需要改變的參數用const進行标記,以便讓編譯器知道參數 不能被改變。如:const PFArray &array1,該方式即為常引用調用。
(4)當成員函數不會修改調用對象的值時,也可以用const來标記該函數。
(5)const要麼不使用,要麼應該使用的地方都用。如一個類類型使用了const參數修飾,那麼在所有在函數調用中不會改變該類型參數的函數,都應該以const修飾。
2. 重載指派操作符。
PFArray & operator = (const PFArray &rightSide);
指派操作符實際上傳回的是一個引用。為什麼要重載指派操作符呢?這就涉及到的淺複制和深複制的問題。
如:PFArray list_a(10), PFArray list_b(20);
list_a = list_b;
如果這裡沒有重載複制操作符,會使用預設的指派操作符來執行它。即簡單地将資料成員進行複制,包括将list_a.a = list_b.a。但是,a指向的是一個動态數組,即記憶體中的位址,進行簡單的指派之後,list_a.a和list_b.a指向了同一段記憶體。二者其一改變,另一必會跟着改變。
而我們希望能夠産生完全獨立于其右邊變量的副本。是以進行運算符重載。
(1)淺複制:
在一個指派操作符中的重載或拷貝構造函數中,如果函數的代碼僅僅是将成員變量的值從一從此對象複制到另一個對象中,這種方式稱為淺複制。預設的指派操作符和拷貝構造函數執行的都是淺複制。
淺複制可以用于類中不包含指針或動态配置設定的資料。
(2)深複制:
如果類中包含指針或動态數組的成員變量,那麼需要自己定義這樣的指派函數,重新配置設定記憶體,拷貝資料。以産生兩個獨立的副本
3. 拷貝構造函數
再定義拷貝構造函數的目的和上面剛剛提到的是一樣的。
PFArray(const PFArray& copyArray);
在需要産生一個對象的副本的時候,就會自動調用複制構造函數。在下面3種情況下,拷貝構造函數會被調用:
(1)當聲明一個類的對象時,使用另一個對象對它進行初始化
(2)當一個函數傳回值為類類型時
(3)當一個類類型的實參傳遞給函數中的傳值調用參數時。