今天早上看了一本資料結構的書關於類和動態儲存的章節。書裡面大概地舉了幾個關於在乙個類裡面動態申請記憶體的例子。我由此想到就算是乙個一般的類也應該具備一定的基本結構,而並不不是乙個類頭、幾個資料成員和成員函式就可以作為乙個類「安全」地使用。
我們先看一些例子。
以前,我看到過有很多人這樣寫乙個類:
class a
private:
int m_count;
};
編寫者目的是獲得a類物件呼叫成員函式getcount的次數。
結果是獲得乙個很小的負數!當然這是乙個很低階的錯誤,現在已經沒有誰會範的了。
哈哈,所以我的第乙個結論是:乙個類應該有乙個使用者自定義的預設建構函式。另外,在我的vc6.0編譯器中,如果乙個類有多個建構函式(但是沒有乙個預設建構函式,即沒有乙個不帶引數的建構函式),它是不會為你自動加上去的,所以自定義的預設構著函式應該是每乙個類都應該有的。
於是改為:
class a
int getcount()
private:
int m_count;
};
錯誤就消失了。
但是加了一些功能以後,另乙個錯誤又出現了。
class b
b(const string &str);
int getint()
private:
int m_count;
string *m_pstr; };
//b::b(const string &str)
如果有一下語句:
//這條
b obj1(「string」)
語句在vc6.0
中不會出現錯誤,但在
c++builder
中就會出現錯誤,具、、
//體原因可以檢視具體編譯器的幫助文件。本文最後也概略講一下。不同編譯器有不同的實
//現。
b obj1(「string」)
,obj2 = obj1;
以上語句只是告訴編譯器要吧
obj1
的資訊安位拷貝到
obj2
中。結果執行語句後,
obj2
的m_pstr
和obj1
的m_pstr
成員指向同一塊記憶體位址。顯然這不是我們想要的結果。如果在較複雜的程式中使用就會埋下隱蔽的禍患。
所以我的第二個結論是:乙個類應該有乙個複製建構函式詳細地告訴編譯器如何複製(初始化)乙個自定義物件。這樣才能使使用者自定義型別使用起來能夠更加「像」
c++內部型別,這也許是
c++「美麗「的地方之一吧
^_^。
哈哈!是不是就完美無缺呢?
of course not.
我們還漏了釋放
b型別中動態建立的物件
*m_pstr
。這個工作要在析構函式中完成。
於是又修改為
class b
b(const string &str);
b(const b &obj);
virtual ~b();
int getint()
private:
int m_count;
string *m_pstr;
};
//b::b(const string &str)
b::b(const b &obj)
b::~b()
其實,我覺得最好是把複製建構函式的孿生子妹
operator=
函式寫上。這樣能夠使類無論是初始化還是賦值的時候能夠正確執行。特別是上面舉的有動態記憶體分配的情況下,就更加應該有這個過載函式。否則當物件作為形式引數傳遞給函式的時候就有可能出錯。就如下面的情況:
int main(void)
}//
在這裡將出現執行期的錯誤!因為
obj0
中的*m_pstr
已經在這之前被釋放掉。}
這是我一點心得。 語句
b obj1(「string」);
在vc6.0
中等價於
b obj1(string(「string」));
vc6.0
自動用串
」string」
生成乙個
string
型別的臨時物件並傳遞給
b的建構函式。
但是在c++builder
中沒有這種功能。
UML 對基本結構建模 類
uml 對基本結構建模 一 類 類是任何物件導向系統中最重要的構造塊。類是對一組具有相同屬性 操作 關係和語義的物件的描述。在圖形上,把乙個類畫成乙個矩形。我們將從下面幾個方面來了解 1 名稱 2 屬性 是已被命名的類的特性,它描述了該特性的例項可以取值的範圍。3 操作 是乙個服務的實現,該服務可以...
UML對基本結構建模 類
類是對一組具有相同屬性 操作 關係和語義的物件的描述。在圖形上,把類畫成乙個矩形。1 名稱 每個類都必須有乙個有別與其他類的名稱。名稱是乙個文字串。單獨的名稱叫做簡單名,用類所在的包的名稱作為字首的類名叫做限定名。繪製的類可以僅顯示它的名稱,如下圖所示。乙個包中的各類的名稱都必須是唯一的 2 屬性 ...
基本資料結構 鍊錶的操作(類)
用模板實現鍊錶 類 鍊錶操作 標頭檔案 list.h ifndef list h define list h include using namespace std template class type class list template class type class listnode t...