C语言面向对象编程(一):封装与继承
? ? 這篇文章中我們先說封裝和繼承。
? ? 先來看封裝。
? ? 所謂封裝,通俗地說,就是一個姑娘化了妝,只給你看她想讓你看的那一面,至于里面是否刮了骨、墊了東西,不給你看。說到封裝就得說隱藏,這是對兄弟概念;其實我理解隱藏是更深的封裝,完全不給你看見,而封裝可能是猶抱琵琶半遮面。封裝在 C++ 語言中有 protected 、 private 關鍵字在語言層面上支持,而 C 語言中沒有這些。 C 有結構體( struct ),其實可以實現封裝和隱藏。
? ? 在 QT 中,為了更好的隱藏一個類的具體實現,一般是一個公開頭文件、一個私有頭文件,私有頭文件中定義實現的內部細節,公開頭文件中定義開放給客戶程序員的接口和公共數據。看看 QObject (qobject.h ),對應有一個 QObjectPrivate (qobject_p.h ) ,其他的也類似。而代碼框架如下:
[cpp] view plaincopy print?? ? 這樣做的好處是顯而易見的,除了預定義好的接口,客戶程序員完全不需要知道實現細節,即便實現經過重構完全重來,客戶程序員也不需要關注,甚至相應的模塊連重新編譯都不要——因為 abc.h 自始至終都沒變過。
? ? 上面代碼有個問題,客戶程序員如何得到 struct st_abc 的一個實例,他不知道 struct st_abc_private 如何實現的呀。 C 中沒有構造函數,只好我們自己提供了:我們可以在 abc.h 中聲明一個類似構造函數的函數來生成 struct st_abc 的實例,名字就叫作 new_abc() ,函數原型如下:
[cpp] view plaincopy print?? ? 到現在為止,封裝和隱藏就實現了,而且很徹底。接下來看繼承。
? ? 什么是繼承?在面向對象層面上不講了,只說語法層面。語法層面上講,繼承就是派生類擁有父類的數據、方法,又添了點自己的東西,所謂子承父業,發揚光大。在 C 語言中可以用結構體的包含來實現繼承關系。代碼框架如下:
? ? 繼承在語法層面上看,有數據成員、函數,數據成員通過上面的方法自動就“繼承”了,至于函數,在結構體表示為函數指針,其實也是一個數據成員,是個指針而已,也會自動“繼承”。之所以還要在這里列出來說明,是因為 C++ 中有一個很重要的概念:重載。要在 C 中完整實現有點兒麻煩。
? ? 重載,我們常說的重載大概有三種含義:
- 其一,函數重載,指函數名字一樣,參數個數、類型不一樣的函數聲明和實現。由于 C 編譯器的緣故,不支持。不過這個影響不大。
- 其二,重定義或者說覆蓋,指派生類中定義與基類簽名一樣(名字、返回值、參數完全一樣)的非虛函數,這樣派生類的中的函數會覆蓋基類的同簽名函數,通過成員操作符訪問時無法訪問基類的同簽名函數。
- 其三,虛函數重寫,指在派生類中實現基類定義的虛函數或純虛函數。虛函數是實現多態的關鍵,可以在結構體中使用函數指針來表達,但要完全實現,也很麻煩。
? ? 我們平常在交流時通常不明確區分上面三種類型的重載,這里出于習慣,也不作區分。
? ? 好了,第一篇就到這里,有時間會往下續。
總結
以上是生活随笔為你收集整理的C语言面向对象编程(一):封装与继承的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: docker mysql5.7 主从_d
- 下一篇: android 代码植入,Android