由於本文是面對C語言基礎的(因為我就是從C學起來的),而MFC是利用C++類技術構建起來的。因此有必要在此為只瞭解C的朋友們,普及一下C++語言中類的概念。熟悉C++的朋友可以跳過本部分。從總體來說C++是向下相容C的,你可以很不費力氣地將用C編好了的程式拿到C++環境下編譯執行。其C++只不過是在C的基礎上添加物件導向技術(OOP),也就是類的概念,且值得一提的是C與C++都是由美國的貝爾實驗室(在之前我只知道發明過電話)發明的。
一、什麼是類?
按一些書本上的定義來說“就是一種複雜的資料類型,它是將不同類型的資料和與這些資料相關的操作封裝在一起的集合體。因此,類中的資料具有隱藏性,類還具有封裝性。”嗯,類還像上面的那句話一樣,具有很強的抽象性。讓我來用一個例子來解釋類吧。 嗯,我們世界上有一個生物種類叫做鳥,在C++上世界我們也可以製作一個類叫做鳥類。它應該有頭,有軀幹,有腿,有內髒,還有一個非常重要的翅膀。於是,其類描述如下:
class Aves
{
char m_strHead[10];
char m_strTrunk[10];
char m_strCrura[10];
char m_strWing[10];
char m_strBowels[10];
};
哈,這樣一個鳥類建立好了,怎麼樣與C中結構體沒什麼兩樣吧。(在C++中struct與class基本上是同義字,過一會兒會說到它們有什麼不同的。)如果你想建立一個小鳥的話,不用像C中那樣麻煩地打struct Aves XXX,而是直接使用Aves XXX就可以了,不打前面的struct或class。在人類對鳥類形成概念之前,鳥的翅膀、軀體等等就真的存在了(沒有人有疑議吧?),但在人們根本不知道鳥的那對長滿羽毛的撲扇撲扇就可以飛的東西叫什麼名字,也不會知道翅膀這個詞指的是什麼意思。現在我們的這個C++鳥類也正處於這個狀態,在那些成員變數中沒有被賦與任何值。而現實生活中,一個種類中的具體名字是在一個類對象形成初期被命名的,這是一個名詞初始化的過程。在C++類中,當建立一個類對象時總也要有一個初始化各成員變數的過程,於是建構函式被引入了。它在一個執行個體被聲明和被建立(這兩個有一些區別)時調用。我們的C++鳥類各個成員變數的賦值命名就可以利用它來實現:
class Aves
{
Aves ()
{
strcpy(m_strHead, "Head");
strcpy(m_strTrunk, "Trunk");
strcpy(m_strCrura, "Crura");
strcpy(m_strWing, "Wing");
strcpy(m_strBowels,”Bowels”);
}
char m_strHead[10];
char m_strTrunk[10];
char m_strCrura[10];
char m_strWing[10];
};
瞧,我是怎麼在類裡面建立一個建構函式的。一個類的建構函式的名字要與其類名同名,且不能有傳回值,void也不行。我們在建構函式中,對各個成員函數命名。當Aves bird;時(聲明一個bird對象),Aves類的建構函式將會被調用,把bird.m_strHead,bird.m_strTrunk等等成員變數分別賦值為”Head”,”Trunk”。這樣一講,希望大家對建構函式有了一定的瞭解了。我們既然有建構函式可以對類成員進行初始化,那麼用什麼來對類成員銷注呢?說白了就是有在建立類對象時調用的函數,什麼函數是在類對象被刪除時調用的函數呢?那就是解構函式,其命名規則與建構函式是一樣的,只不過需要在其函數名前緊加一個~(波浪號),且不能有參數。如我們的類就是~Aves(); 至於解構函式具體作用嘛…舉個例子來說,當在建構函式中申請了一段記憶體,我們就必須在解構函式中釋放這段記憶體,否則會記憶體流失。那麼什麼時候會引發聲明的類對象被刪除呢?要解決這個問題,我還需要借用一個叫名域(name space)的概念。當系統執行指標離開聲明的類對象所在名域時,就會引發類對象的刪除(類型的有效型也可以如此解釋)。而名域這個概念最實稱的理解就是一對大括弧,在這對括弧內的空間就是一個名域。(當然名域其實不是這麼簡單的。如類本身就是一個名域,還可以自己設定一個名域,用於型別宣告設定,可以用已有的類型衝突。名域真實用途是這個。具體含義參見《C++標準庫》,圖書大廈有侯捷先生的譯本)比如:
{//名域1
char * strValue;
{//名域2
Aves bird;
{//名域3
strValue=bird.m_strWing;
}
}//<<就在後大括弧這裡引發了bird對象的解構函式
strValue=”Blue Atlantis”;
}