標籤:c語言 c 物件導向 gobject
本專欄文章列表
一、何為物件導向
二、C語言也能實現物件導向
三、C++中的不優雅特性
四、解決封裝,避免介面
五、合理使用模板,避免代碼冗餘
六、C++也能反射
七、單例模式解決靜態成員對象和全域對象的構造順序難題
八、更為進階的前置處理器PHP
二、C語言也能實現物件導向
今天要為大家介紹C語言的物件導向設計方法,正如題記上面所說,物件導向是一種思想,而並非是一種語言,我們將會介紹C語言實現的物件導向開發方式。
簡單實用的C語言物件導向設計思路
眾所周知,C++中的物件導向十分方便,但在C中,並沒有類,但我們可以通過C的結構體來實現,然後,手動將this指標傳入
目前這個方法,應該是C語言設計中,簡便易用的方式,而且能較好的體現物件導向的設計思路,然而遺憾的是,沒有繼承和多態。
例如,我們這樣一個C++類
class test {public: test(char* str, int k) { this->str = str; this->k = k; } void ShowMessage() { for (int i = 0; i < k; ++i) printf("%s\n", str); }private: int k; char* str;};
那麼我們可以這樣轉換為一個C類
/* test.h */typedef struct _test { int k; char* str;} test;test* TestCreate();void ShowMessage(test*);
/* test.c */test* TestCreate() { return (test*) malloc(sizeof(test));}void ShowMessage(test* t) { int i; for (i = 0; i < t->k; ++i) { printf("%s\n", t->str); }}
其實思路也很清晰,思路簡單易懂,實現也很清新明快,在各類C工程中使用極為廣泛。
複雜的基於GObject的物件導向程式設計
如果你希望學習C語言的GUI程式設計,那麼,必定要學習的就是GObject的類實現方式。
GObject相當於從C層面上類比了一個C++的類物件模型,實現當然相對複雜的多。
下面我們來實際看一下一個GTK的視窗類別,這是GTK+-3.0的一段範例:
/* appwin.h */#ifndef APPWIN_H#define APPWIN_H#include "app.h"#include <gtk/gtk.h>/* 該類的類型定義以及類型轉換宏 */#define APP_WINDOW_TYPE (app_window_get_type())#define APP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APP_WINDOW_TYPE, AppWindow))/* 該類分成兩部分,一部分是成員,一部分是類本身 */typedef struct _AppWindow AppWindow;typedef struct _AppWindowClass AppWindowClass;GType app_window_get_type (void);AppWindow* app_window_new (App *app);void app_window_open (AppWindow *win, GFile *file);#endif // APPWIN_H
而其真實的定義是在.c檔案中
struct _AppWindow{ GtkApplicationWindow parent;};struct _AppWindowClass{ GtkApplicationWindowClass parent_class;};typedef struct _AppWindowPrivate AppWindowPrivate;struct _AppWindowPrivate{ GSettings *settings; GtkWidget *stack; GtkWidget *search; GtkWidget *searchbar; GtkWidget *searchentry; GtkWidget *gears; GtkWidget *sidebar; GtkWidget *words; GtkWidget *lines; GtkWidget *lines_label;};G_DEFINE_TYPE_WITH_PRIVATE(AppWindow, app_window, GTK_TYPE_APPLICATION_WINDOW);/* 後面有具體的實現方法,這裡就不一一列舉 */
我們發現,這種定義方式比C++中的其實更有優勢,封裝的更加徹底。為何這樣說呢?首先,我們的聲明檔案十分的簡潔,如果公開方法不修改的話,那麼將其餘內容如何改動,都不會影響我們的外部介面。
其次,由於需要顯示的向GObject註冊,那麼動態進行類註冊就成為可能,這樣的設計優勢表現在哪裡呢?多語言的互連性就很好了,因為很多動態語言,是支援類的動態載入以及反射載入的。
另外,vala語言就是基於GObject類型的,他是一門新興的編譯時間語言,但其也有很多動態語言的特性,用其開發gtk程式,比C具有明顯的優勢。
C和C++的物件導向專題(2)——C語言也能實現物件導向