OOC 用C實現物件導向

2021-06-08 17:11:02 字數 4395 閱讀 2689

1、  概述

c語言是一種面向過程的程式語言,而c++是在c語言基礎上衍生來了的物件導向的語言,實際上,很多c++實現的底層是用c語言實現的,如在visual c++中的inte***ce其實就是struct,查詢inte***ce的定義,你可以發現有這樣的巨集定義:

#ifndef inte***ce

#define inte***ce struct

#endif

c++在語言級別上新增了很多新機制(繼承,多型等),而在c語言中,我們也可以使用這樣的機制,前提是我們不得不自己實現。

本文介紹了用c語言實現封裝,繼承和多型的方法。

2、  基本知識

在正式介紹c語言實現封裝,繼承和多型事前,先介紹一下c語言中的幾個概念和語法。

(1)    結構體

在c語言中,常把乙個物件用結構體進行封裝,這樣便於對物件進行操作,比如:1

strcut point;

結構體可以巢狀。因而可以把乙個結構體當成另乙個結構體的成員,如:1

struct circle ;

該結構體與以下定義完全一樣(包括記憶體布置都一樣):1

struct circle ;

(2)    函式指標

函式指標是指標的一種,它指向函式的首位址(函式的函式名即為函式的首位址),可以通過函式指標來呼叫函式。

如函式:

int func(int a, int n);

可以這樣宣告函式指標:

int (*pfunc)(int a, int n);

這樣使用:

pfunc = func;

(*pfunc)(a, n);【或者pfunc(a, n)】

可以用typedef定義乙個函式指標型別,如:

typdef int (*func)(int a, int n)

可以這樣使用:

int cal_a(func fptr, int a, int n)

(3)    extern與static

extern和static是c語言中的兩個修飾符,extern可用於修飾函式或者變數,表示該變數或者函式在其他檔案中進行了定義;static也可用於修飾函式或者變數,表示該函式或者變數只能在該檔案中使用。可利用它們對資料或者函式進行隱藏或者限制訪問許可權。

3、  封裝

在c語言中,可以用結構+函式指標來模擬類的實現,而用這種結構定義的變數就是物件。

封裝的主要含義是隱藏內部的行為和資訊,使用者只用看到對外提供的介面和公開的資訊。有兩種方法實現封裝:

(1)    利用c語言語法。在標頭檔案中宣告,在c檔案中真正定義它。

這樣可以隱藏內部資訊,因為外部不知道物件所佔記憶體的大小,所以不能靜態的建立該類的物件,只能呼叫類提供的建立函式才能建立。這種方法的缺陷是不支援繼承,因為子類中得不到任何關於父類的資訊。如:

//標頭檔案:point.h

#ifndef point_h

#define point_h

struct point;

typedef struct point point;

point * new_point(); //newer a point object

void free_point(point *point_);// free the allocated space

#endif

//c檔案:point.c

#include」point.h」

strcut point ;

point * new_point()

void free_point(point *point_)

(2)    把私有資料資訊放在乙個不透明的priv變數或者結構體中。只有類的實現**才知道priv或者結構體的真正定義。如:

#ifndef point _h

#define point_h

typedef struct point point;

typedef struct pointprivate pointprivate;

strcut point ;

int get_x(point *point_);

int get_y(point *point_);

point * new_point(); //newer a point object

void free_point(point *point_);// free the allocated space

#endif

//c檔案:point.c

#include」point.h」

struct pointprivate

int get_x(point *point_)

int get_y(point *point_)

//others…..

4、  繼承

在c語言中,可以利用「結構在記憶體中的布局與結構的宣告具有一致的順序」這一事實實現繼承。

比如我們要設計乙個作圖工具,其中可能涉及到的物件有point(點),circle(圓),由於圓是由點組成的,所有可以看成circle繼承自point。另外,point和circle都需要空間申請,空間釋放等操作,所有他們有共同的基類base。

//記憶體管理類new.h

#ifndef new_h

#define new_h

void * new (const void * class, ...);

void delete (void * item);

void draw (const void * self);

#endif

//記憶體管理類的c檔案:new.c

#include 「new.h」

#include 「base.h」

void * new (const void * _base, ...)

return p; }

void delete (void * self)

void draw (const void * self)

//基類:base.h

#ifndef base_h

#define base_h

struct base ;

#endif

//point標頭檔案(對外提供的介面):point.h

#ifndef   point_h

#define  point_h

extern const void * point;                /* 使用方法:new (point, x, y); */

#endif

//point內部標頭檔案(外面看不到):point.r

#ifndef point_r

#define point_r

struct point ;

#endif

//point的c檔案:point.c

#include 「point.h」

#include 「new.h」

#include 「point.h」

#include 「point.r」

static void point_draw (const void * _self)

static const struct base _point = ;

const void * point = & _point;

//測試程式:main.c

#include 「point.h」

#include 「new.h」

int main (int argc, char ** argv)

同樣,circle要繼承point,則可以這樣:1

struct circle ;

5、  多型

可以是用c語言中的萬能指標void* 實現多型,接上面的例子:1

//測試main.c

void * p = new(point, 1, 2);

void * pp = new(circle, 1, 2);

draw(p); //draw函式實現了多型

draw(pp);

delete(p);

delete(pp);

6、  總結

c語言能夠模擬實現物件導向語言具有的特性,包括:多型,繼承,封裝等,現在很多開源軟體都了用c語言實現了這幾個特性,包括大型開源資料庫系統postgresql,可移植的c語言物件導向框架gobject,無線二進位制執行環境brew。採用c語言實現多型,繼承,封裝,能夠讓軟體有更好的可讀性,可擴充套件性。

7、  參考資料

(1)        《c語言中extern和static用法》:

(2)        《三、使用gobject——私有成員和靜態變數》:

(3)        《技巧:用 c 語言實現程式的多型性》:

(4)        書籍《object-oriented programming with ansi-c》

C語言 實現 物件導向程式設計 OOC

結構體,函式指標,聚合組合等知識。inside the c object model object oriented programming with ansi c 這裡是csdn上前幾章的中文翻譯 wiki上有全部的中英文互譯 不過建議對照英文原著閱讀 這裡有object oriented pro...

python物件導向 用函式實現物件導向原理

類的定義 乙個抽象的概念,儲存一些共有的屬性和特徵 物件 物件代表具體事物的特徵功能,是類的例項 物件導向程式設計 通過函式實現物件導向設計 defdog name,type,gender defjiao dog1 print 你看 s 狗再叫 dog1 name 函式的區域性作用域 defslee...

c實現物件導向

c語言的結構體裡面沒有函式,但是c 裡面有函式,所以今天實現乙個c語言物件導向的程式 1 封裝 include include include typedef struct cmd newcmd void run newcmd pcmd void print newcmd pcmd int main...