1、數據抽象與封裝
數據抽象是一種接口和實現相分離的編程技術,設計者關心的是如何實現這些接口,而使用者僅僅知道這些接口,抽象地考慮這些接口做什麼的就可以了,不必去考慮如何實現這一層次。
封裝是將低層次的元素結合起來組成高層次的實體,比如函數是封裝的一種形式,函數本身可以看做一個大的實體,封裝了函數裡面所執行的實現細節,於是被封裝的元素隱藏了他們的實現細節,可以通過調用該函數 來執行函數封裝的功能,但不能直接訪問函數所執行的語句。同理,類也是一個封裝的實體,類是許多成員的大集合,隱藏了實現該類類型的成員。
標准庫類型vector在使用的時候只考慮它能執行的操作,即值考慮接口,所以具有抽象特性,同時外部又無 法了解和訪問該類型是如何實現其細節的,所以又具有封裝特性。但是數組就不一樣了,用戶可以通過訪問數 組的內存來直接對數組進行操作,所以雖然數組的定義類似於vector,但數組既不具有抽象特性,也不具有封裝特性。
2、類的復制構造函數與默認構造函數
在類中是否需要顯示定義類的復制構造函數,就看在進行類的對象復制的時候是否就相當於復制對象的所有數據成員,如果不是,就需要顯示定義復制構造函數。因為隱式的復制構造函數是按照值進行復制的,因此,對於data成員的隱式復制完成之後,兩個對象的data成員將指向相同的內存地址,在銷毀的時候,會被釋放兩次。
class string
{
public:
string();
string(const char *str);
~string();
private:
char *data;
}
所以常常是類中有指針成員時,要求定義復制構造函數。
3、要考慮用重載以避免隱含的類型轉換
比如:在字符串類String,class String{...},要進行比較,
bool operator==(const String &,const String&)
{
//代碼中某處有下面的語句
if(caseOfString=="mingzi")
{...}
}
很明顯,"程序中就相當於if(caseOfString==String("mingzi")),而我們只是為了讀取"mingzi",而沒有必要去復制。所以要用重載以避免轉換,如
bool operator==(const String &str,const char *str1),bool operator==(const char *str1,const String &str)。