程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C和C++的面向對象專題(2)——C語言也能實現面向對象

C和C++的面向對象專題(2)——C語言也能實現面向對象

編輯:C++入門知識

C和C++的面向對象專題(2)——C語言也能實現面向對象


本專欄文章列表

一、何為面向對象

二、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 

/* 該類的類型定義以及類型轉換宏 */
#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具有明顯的優勢。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved