標籤:
有人認為物件導向是C++/Java這種進階語言的專利,實際不是這樣,物件導向作為一種設計方法,是不限制語言的。只能說,用C++/Java這種文法來實現物件導向會更容易、更自然一些。
在本節中,就展示如何在C語言中實現物件導向編程,這是一件吃力的工作。寫這些的目的有兩個:
① 更好的掌握C++中的class的概念。學習了本章,就知道C程式員的無耐,就知道為什麼要發明一個class的概念、為什麼要有成員函數等等。
② 為C程式員提供一個參考設計。由在存在某些場合,只允許用C語言來編程,不允許用C++來編程。這時候,可以參考本篇的代碼,用C的文法來類比C++的類來實現物件導向編程。
本篇按從易到難的順序,提供幾種基於C struct的物件導向的寫法。在本節的展示中,統一以.c尾碼命名檔案,也就是說,是以C語言的文法來書寫代碼。C語言和C++的struct寫法略有區別,請參考附錄《C++與C的區別》。
權利聲明:作者擁有本書的全部權利。作者授權任何人都可以自由轉載本網站發布的內容,但轉載時必須遵守以下限制: ①轉載時必須全文轉載,不得有任何修改,必須包含“權利聲明”和“官網地址” ② 僅限於網路轉載,即最終結果公佈於網路上。凡是不遵守以上兩條的轉載行為視為侵權行為。除非本人允許,任何人不得將本網站內容內容用於任何的其他用途。
官網地址: http://www.afanihao.cn/ 留言請到http://www.afanihao.cn/kbase/
1.1 第1種方法
這種方法只適合單一執行個體的對象。以印表機Print對象為例,系統中只存在一台印表機,此時按以下方法提供介面,
首先,給出printer.h,裡面寫明對外的介面,
/////////////////// printer.h begin ///////////////
#ifndef _PRINTER_H
#define _PRINTER_H
int pr_open(); // 開啟印表機
void pr_close(); // 關閉印表機
void pr_print(const char* text); // 列印文本
#endif
/////////////////////////////////////////////////////
其次,給出printer.c,給出函數介面的實現。由於沒有辦法操縱一台真實的印表機,那樣代碼太複雜,作者不容易理解。所以這裡使用“虛擬印表機”的概念,所謂“列印”,只是將檔案寫到指定的檔案c:\printer.txt裡,
/////////////////// printer.c ///////////////
#include <stdio.h>
#include "printer.h"
// 定義
typedef struct
{
FILE* outfile;
}printer_t;
// 定義唯一執行個體
static printer_t pr = { NULL };
// 開啟印表機
int pr_open()
{
pr.outfile = fopen("c:/printer.txt", "ab");
if(pr.outfile == NULL)
return -1;
return 0;
}
// 關閉印表機
void pr_close()
{
if(pr.outfile)
{
fclose(pr.outfile);
pr.outfile = NULL;
}
}
// 列印文本
void pr_print(const char* text)
{
fprintf(pr.outfile, text);
}
/////////////////// ///////////////
在main.c中這麼調用
/////////////////// main.c ///////////////
#include "printer.h"
void main()
{
pr_open(); // 開啟
pr_print("aaabbbccc\n"); // 輸出文本
pr_close(); // 關閉
}
可以總結出這種寫法的特點:
(1) 雖然是物件導向,但只有一個對象,該對象外部不可見;
(2) 外界只能通過函數介面該對象的功能。可以發現,函數中並沒有傳入對象的指標。
1.2 第2種方法
當可以建立多個對象時,使用此種方法來實現。仍然前面的printer為例,其實這個printer只是一個“虛擬”的印表機,最終目標是輸出到一個本地的檔案。那麼,可以允許建立多個printer對象的。
標頭檔printer.h中定義對象,在提供的介面函數都有對象指標,其中~open函數用於建立一個對象,~close用於銷毀對象,
///////////////////printer.h ///////////////
#ifndef _PRINTER_H
#define _PRINTER_H
#include <stdio.h>
typedef struct
{
FILE* outfile;
}printer_t;
printer_t* pr_open(const char* filename); // 開啟印表機
void pr_close(printer_t* pr); // 關閉印表機
void pr_print(printer_t* pr, const char* text); // 列印文本
#endif
下面是它的實現,
///////////////////printer.c ///////////////
#include <stdio.h>
#include <stdlib.h>
#include "printer.h"
// 開啟印表機
printer_t* pr_open(const char* filename)
{
printer_t* pr = (printer_t*)malloc(sizeof(printer_t));
pr->outfile = fopen(filename, "ab");
if(!pr->outfile)
{
free(pr);
return NULL;
}
return pr;
}
// 關閉印表機
void pr_close(printer_t* pr)
{
fclose(pr->outfile);
free(pr);
}
// 列印文本
void pr_print(printer_t* pr, const char* text)
{
fprintf(pr->outfile, text);
}
在main.c的調用這個對象,
///////////////////main.c ///////////////
#include "printer.h"
void main()
{
printer_t* pr = pr_open("c:/1.txt");
pr_print(pr, "aaabbbccc\n");
pr_close(pr);
}
至此,物件導向已經比較完整,它有3個要素:
① 對象的建立:使用pr_open函數來建立一個對象,允許建立多個對象;
② 對象的銷毀: 使用pr_close來銷毀對象
③ 對象的功能介面: pr_print是其功能介面,注意這個函數的第一個參數就是指向了一個對象
1.3 第3種方法
這種方法是對方法2的升級,理念和方法2一樣。它是在形式上和C++的class基本一致,或許可以說,C++的class是從這種方法演化而來的。
。。。本節內容不公開,更多內容請購買紙質教材,謝謝支援!。。。
如何在C語言裡實現“物件導向編程”