這裡強調是物件導向程式設計的易錯點和常用技巧,嚴格來說大多數時候使用的封裝和繼承來完成的物件程式設計只能算是基於物件的程式設計,結合物件的繼承和多型特性編寫的程式才算是物件導向程式設計。
繼承涉及到一些複製控制特性,主要如下:
a).不顯式呼叫父類建構函式時,子類建構函式會先隱式呼叫父類預設建構函式
b).子類析構函式會先隱式呼叫父類析構函式
c).子類複製建構函式和賦值過載不會隱式呼叫父類
d).只要子類中存在和父類同樣名字的函式,就算子類和父類的函式宣告不一樣,父類的函式也一定會被覆蓋
如下,定義類
class ctest1
;class ctest2 : public ctest1
;
可如下呼叫
error!
t21.ctest1::display(10);
t21.display(10,20);
看以看到,儘管子類沒有定義單個引數的過載,仍然不能呼叫父類display函式,除非顯式呼叫父類的display(10)。
c++有個不好的地方,多型性必須使用指標或引用才能體現出來,即使用指標指向不同的子類物件,這時候虛函式生效會呼叫不同子類的同乙個函式,從而體現多型性,但是這樣帶來的乙個不方便就是物件的生存週期的管理,必須自己管理指標物件。反過來,不使用指標,直接使用物件,可以利用構造和析構函式完成具體的管理,但是這樣就喪失了多型性。
為了既可以利用多型,也支援自動管理,我們引入了控制代碼類。
1.管理基類指標
先看第一種控制代碼類,這種控制代碼類主要用來管理基類指標,控制代碼類類似智慧型指標,如下:
class cpeoplehandle
virtual ~cpeoplehandle()
cpeoplehandle(const cpeoplehandle& h)
cpeoplehandle& operator=(const cpeoplehandle& h)
cpeople* operator->()
cpeople& operator*()
private:
cpeople* m_ppeople;
int* m_prefcnt;
......
這裡我們對基類指標cpeople*做了包裝,複製控制、*和->過載都和智慧型指標類似。不同的在於,定義建構函式如下,
cpeoplehandle(cpeople& p): m_ppeople(p.clone()), m_prefcnt(new int(1))
針對不同的子類,呼叫他們的clone虛函式建立對應的物件,例如
class cpeople
;class cman : public cpeople
;class cwoman : public cpeople
;
clone定義如下
cpeople* cpeople::clone()
cman* cman::clone()
cwoman* cwoman::clone()
注意,虛函式支援子類返回的型別為子類指標。
這樣就使用控制代碼類管理了不同子類的物件,支援多型且支援引用計數。
可如下使用
vectorvcpeople;
vcpeople.push_back(cpeople(10));//隱式構造cpeoplehandle
vcpeople.push_back(cpeople(20));
vcpeople.push_back(cman(18));
vcpeople.push_back(cwoman(14));
for (int i=0; idispaly();
}
所有物件統一一種控制代碼類來包裝,是不是很方便?
2.管理和建立基類指標
上面介紹的控制代碼類主要負責包裝基類指標,原始基類物件是自己在類外定義的。那能不能讓控制代碼類做更多的事情?如下,我們只定義類層次結果,然後讓控制代碼類來負責管理基類指標,同時負責建立不同的子類物件。
這裡我們假設這樣一種需求:
要求判斷指定的一段文字中是否存在乙個指定的字母,要求支援與或非運算。如對於"abcabdabc,"『a』 | ('c' & 'd'),返回為真。
1.首先,控制代碼類封裝了基類指標。
2.然後,控制代碼類還負責建立不同的子類物件。
如下定義繼承關係
cquery為基類,是基本查詢類,成員變數m_chquery為待查詢的字元,虛函式i***ist執行查詢操作,如下
virtual bool i***ist()
cnotquery支援求反運算,包含指向基類的指標,因為控制代碼類管理基類指標,我們直接換成控制代碼類,i***ist實現如下
virtual bool i***ist()
candquery和corquery都繼承cbinary,支援二元與或操作,包含兩個基類指標,即控制代碼類,i***ist實現分別如下
virtual bool i***ist()
virtual bool i***ist()
這裡的i***ist全部定義為private,因為這些類的建立和介面匯出都由控制代碼類管理了,
控制代碼類定義如下
class cqueryhandle
;
管理基類指標的部分就不說了,和前面的一致,這裡注意的是過載操作符和定義兩個建構函式以支援類的建立,如下
//統一建立和管理
cqueryhandle::cqueryhandle( char c )
cqueryhandle::cqueryhandle( cquery* p )
//操作符過載,隱式構造
cqueryhandle operator!( const cqueryhandle& q )
cqueryhandle operator&( const cqueryhandle& q1, const cqueryhandle& q2 )
cqueryhandle operator|( const cqueryhandle& q1, const cqueryhandle& q2 )
匯出介面i***ist定義如下
bool cqueryhandle::i***ist()
如下使用
cqueryhandle aa= (cqueryhandle('a') | cqueryhandle('x')) & cqueryhandle('0');
cout << aa.i***ist() << endl;
可以看到,這裡我們根本沒有定義基類和子類物件,基類和子類主要用來定義繼承關係,我們直接操作的只有控制代碼類,基類和子類對於使用者來說是私有的。 c 物件導向程式設計 物件導向
什麼是物件導向 是對現實世界理解和抽象的方法。物件導向程式設計的特點 易維護,易擴充套件,靈活性好,重用 類 對事物的抽象定義,即事物具有的共同特徵和行為。物件 即對類進行例項 類是抽象的,物件是具體的 類的定義 語法 訪問修飾符 class 類名類的成員 包括字段,屬性,方法,常量,事件和索引器等...
C 物件導向程式設計
1.1 類與物件 物件 object 是類 class 的乙個例項 instance 如果將物件比作房子,那麼類就是房子的設計圖紙。所以物件導向程式設計的重點是類的設計,而不是物件的設計。類可以將資料和函式封裝在一起,其中函式表示了類的行為 或稱服務 類提供關鍵字public protected 和...
C 物件導向程式設計
物件導向程式設計 以物件為中心,將資料和方法封裝在一起。三要素 抽象繼承 多型 五個基本原則 單一職責原則 就乙個類而言,應該有且僅有乙個引起它變化的原因。開放 封閉原則 是說軟體實體 類 模組 函式等等 應該可以擴充套件,但是不可修改。黎克特制替換換原則 子類應當可以替換父類並出現在父類能夠出現的...