一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

基于C語言的面向對象編程

 黃南山 2017-06-26

 嵌入式軟件開發(fā)中,雖然很多的開發(fā)工具已經(jīng)支持C++的開發(fā),但是因為有時考慮運行效率和編程習慣,還是有很多人喜歡用C來開發(fā)嵌入式軟件。Miro Samek說:“我在開發(fā)現(xiàn)場發(fā)現(xiàn),很多嵌入式軟件開發(fā)者(絕大多數(shù)是電子工程師)都有工作背景而且他們常常不喜歡用C++。”【1】

面向對象編程(OOP)是一種方法,而不依賴于某特定語言。一般認為,OOP只能使用面向對象的語言,如Smalltalk、C++或Java等固有支持OOP的語言。但是,OOP并不依賴于特殊的語言,只要實現(xiàn)了OOP的封裝、繼承和多態(tài)性這三大基本特性,使用非固有支持面向對象的語言,也可以進行面向對象的編程。

面向對象編程方法的三大基本特性是:

  • 封裝性---封裝數(shù)據(jù)(屬性)與函數(shù)(方法)到類中的能力;
  • 繼承性---基于已有的類定義新類的能力;
  • 多態(tài)性---在運行時具有一致接口的對象相互替換的能力。

雖然這些特性與面向對象語言有關,但幾乎可以用任何語言實現(xiàn)面向對象的這三大基本特性,包括C語言和匯編語言等。事實上,不管實現(xiàn)語言為何,任何大的軟件系統(tǒng)幾乎都會以某種形式使用抽象(封裝)、繼承或多態(tài)性。

1.C語言的封裝

1.1 封裝的本質

在C++中,一個類中包括屬性和方法,聲明一個類例子如下:

class A {
  int n;                 //屬性
  A();                   //構造函數(shù)
  void function1(int x){...}; //方法
}

在C++中,用A生成兩個對象a1和a2時,如下:

A a1 = new A();
A a2 = new A();

對于非模板類A,在內(nèi)存中,對所有的對象,方法function1只有一個拷貝,而對每個對象,都有自己獨立的一份屬性拷貝,也就是有多個屬性拷貝,所謂創(chuàng)建一個對象,也就是創(chuàng)建一套屬性。

調(diào)用a1.function1()和a2.function1()時,每個對象使用自己的屬性n1和n2,而方法代碼在內(nèi)存中是同一套。這就相當于調(diào)用functin1(n1,x)和function1(n2,x)。

在C語言實現(xiàn)中,把所有的屬性放到一個結構中,所有方法中第一個參數(shù)用一個指向自己屬性結構的一個指針me, 如下:
function1(struct *me, ...);
這個方法對所有對象有用,具體對哪個對象的屬性操作,可以用me來區(qū)分。

1.2 具體例子

生成兩個文件person.h和person.c,定義一個Person結構類型(也就是類名稱),把屬性放到結構中,方法中的第一個參數(shù)me是Person的引用指針。

pers1.2on.h文件:
在頭文件中以結構定義類成員屬性,聲明構造方法和析構方法,聲明public方法。

#ifndef PERSON_H
#define PERSON_H

    /*1.定義類成員屬性(沒有隱藏)*/
    typedef struct PersonTag {
        String name__; /*屬性*/
        uint8_t age__; /*屬性*/
    }Person;  
      
    /*2.聲明構造和析構函數(shù)*/
    void Person_Ctor(Person *me, uint8_t age);/*第一個參數(shù)指向屬性*/
    void Person_Xtor(Person *me);/*第一個參數(shù)指向屬性*/

    
    /*3.聲明public方法*/
    void Person_setName(Person *me, String name);/*第一個參數(shù)指向屬性*/
    String Person_getName(Person *me);/*第一個參數(shù)指向屬性*/
    
    /*4.聲明private方法(要在person.c文件中聲明)*/ 
      
#endif

person.c文件:
在.c文件中聲明private方法,并實現(xiàn)所有的方法。

#include "person.h"

/*1.聲明private方法, 用static修飾*/
static void Person_setAge(Person *me, uint8_t age);/*第一個參數(shù)指向屬性*/
static uint8_t Person_getAge(Person *me);/*第一個參數(shù)指向屬性*/

/*2.實現(xiàn)構造和析構函數(shù)*/
void Person_Ctor(Person *me, uint8_t age) {
    me->age__ = age;
}
void Person_Xtor(Person *me) {
    ...
}

/*3.實現(xiàn)public方法*/
void Person_setName(Person *me, String name) {
    me->name__ = name;
}
String Person_getName(Person *me) {
    return me->name__;
}

/*4.實現(xiàn)private方法*/
void Person_setAge(Person *me, uint8_t age) {
    me->age__ = age;
}
uint8_t Person_getAge(Person *me) {
    return me->age__;
}

app.c中使用Person類:

#include "person.h"  /*包含頭*/
void main() {
    String tmp;
    Person l_ps1; /*創(chuàng)建一個實例,實際就是一個屬性*/
    Person l_ps2; /*創(chuàng)建另一個實例,實際就是另一個屬性*/
    
    Person_Ctor(l_ps1, 30);      /*顯式調(diào)用構造函數(shù)*/
    Person_setName(l_ps1,"張三"); /*使用其public方法*/
    tmp = Person_getName(l_ps1); /*使用其public方法*/
    
    Person_Ctor(l_ps2, 30);       /*使用其public方法*/
    Person_setName(l_ps2, "李四"); /*使用其public方法*/
    tmp = Person_getName(l_ps2);  /*使用其public方法*/
}

2.C語言的繼承

Student繼承自Person, 繼承類屬性結構的第一個參數(shù)指向父類屬性,這樣可以滿足Liskov替換原則

student.h文件:
在頭文件中以結構定義類成員屬性,并聲明構造、析構函數(shù)和public方法。

#ifndef STUDENT_H
#define STUDENT_H
#include "person.h"  /*包含父類頭*/

    /*1.定義類屬性(沒有隱藏)*/
    typedef struct StudentTag {
        Person super;   /*第一個參數(shù)指向父類Person,繼承父類屬性*/
        uint8_t code__; /*子類添加的屬性*/
    }Student;  
      
    /*2.聲明構造和析構方法*/
    void Student_Ctor(Student *me, uint8_t code);
    void Student_Xtor(Student *me);
    
    /*3.聲明public方法*/
    void Student_setCode(Student *me, uint8_t code);
    uint8_t Student_getCode(Student *me);
    
    /*4.聲明private方法(在.c文件中聲明)*/ 
      
#endif

student.c文件:
在.c文件中聲明private方法,實現(xiàn)所有的構造方法和析構方法,實現(xiàn)所有的public和private方法。

#include "student.h"

/*1.聲明private方法*/
static void XXX(Student *me, ...);
 

/*2.構造和析構方法實現(xiàn)*/
void Student_Ctor(Student *me, String name, uint8_t code) {
    Person_Ctor((Person*)me, name);/*先調(diào)用父類構造函數(shù)*/
    me->code__ = code;
}
void Person_Xtor(Person *me) {
    ...
}

/*3.public方法實現(xiàn)*/
void Student_setCode(Student *me, uint8_t code) {
    me->code__ = code;
}
 

app.c中使用Student類:

#include "Student.h"  /*包含頭*/
void main() {
    String tmp;
    Student l_st1; /*創(chuàng)建一個實例,實際就是一個屬性*/
    Student l_st2; /*創(chuàng)建另一個實例,實際就是另一個屬性*/
    
    Student_Ctor(l_st1, "張三, 25);  /*顯式調(diào)用構造函數(shù)*/
    Student_setCode(l_st1, 30); //使用其public方法
    tmp = Student_getCode(l_st1); //使用其public方法
}

3.C語言的多態(tài)性

利用C語言的萬能指針void *p可以實現(xiàn)多態(tài)。略。

4.總結

用C語言可以實現(xiàn)面向對象的三大特性,適合于嵌入式系統(tǒng)的編程,QP的C版本就是這樣實現(xiàn)的。現(xiàn)在很多的開源軟件,包括postgreSQL、GObject等都采用C語言實現(xiàn)面向對象的方法。采用這個方法,使程序具有更好的可讀性、可擴展性,同時保持了C語言的高效性。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲熟妇熟女久久精品 | 尹人大香蕉一级片免费看| 激情五月天深爱丁香婷婷| 日本三区不卡高清更新二区| 男人和女人黄 色大片| 久久综合狠狠综合久久综合 | 国产精品午夜小视频观看| 俄罗斯胖女人性生活视频| 加勒比人妻精品一区二区| 国产毛片不卡视频在线| 日韩欧美一区二区不卡看片| 日韩av亚洲一区二区三区| 欧美成人黄色一区二区三区| 亚洲熟妇熟女久久精品| 欧美日韩国产另类一区二区| 国产精品不卡高清在线观看| 免费高清欧美一区二区视频| 色老汉在线视频免费亚欧| 国产国产精品精品在线| 亚洲一区二区三区中文久久| 亚洲高清一区二区高清| 九九热精彩视频在线播放 | 日本在线视频播放91| 国产日韩中文视频一区| 久久天堂夜夜一本婷婷| 在线视频免费看你懂的| 色哟哟哟在线观看视频| 一区二区三区日本高清| 日韩精品成区中文字幕| 国产欧洲亚洲日产一区二区| 五月婷婷六月丁香狠狠| 亚洲五月婷婷中文字幕| 免费观看在线午夜视频| 欧美在线观看视频免费不卡| 加勒比系列一区二区在线观看| 成人国产激情在线视频| 91香蕉视频精品在线看| 加勒比日本欧美在线观看| 亚洲三级视频在线观看免费| 日韩精品成区中文字幕| 成年人视频日本大香蕉久久|