国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

C語言中的面向對象(2)-C語言的多態(tài)實現

2019-11-17 05:04:29
字體:
來源:轉載
供稿:網友
  相信很多人都看過設計模式方面的書,大家有什么體會呢?Bridge,PRoxy,Factory這些設計模式都是基于抽象類的。使用抽象對象是這里的一個核心。
      
  其實我覺得框架化編程的一個核心問題是抽象,用抽象的對象構建程序的主體框架,這是面向對象編程的普遍思想。用抽象構建骨架,再加上多態(tài)就形成了一個完整的程序。由于C++語言本身實現了繼續(xù)和多態(tài),使用這樣的編程理念(理念啥意思?跟個風,嘿嘿)在C++中是十分普遍的現象,可以說Virtual(多態(tài))是VC的靈魂。
 
  但是,使用C語言的我們都快把這個多態(tài)忘光光了。我常聽見前輩說,類?多態(tài)?我們用的是C,把這些忘了吧。很不幸的是,我是一個固執(zhí)的人。這么好的東西,為啥不用呢。很興奮的,在最近的一些純C代碼中,我看見了C中的多態(tài)!下面且聽我慢慢道來。
 
  1. VC中的Interface是什么

  Interface:中文解釋是接口,其實它表示的是一個純虛類。不過我所要說的是,在VC中的Interface其實就是strUCt,查找Interface的定義,你可以發(fā)現有這樣的宏定義:

       #Ifndef Interface
       #define Interface struct
       #endif

  而且,實際上在VC中,假如一個類有Virtual的函數,則類里面會有vtable,它實際上是一個虛函數列表。實際上C++是從C發(fā)展而來的,它不過是在語言級別上支持了很多新功能,在C語言中,我們也可以使用這樣的功能,前提是我們不得不自己實現。
 
  2.C中如何實現純虛類(我稱它為純虛結構)

  比較前面,相信大家已經豁然開朗了。使用struct組合函數指針就可以實現純虛類。

  例子:     typedef struct {
        void  (*Foo1)();
        char  (*Foo2)();
        char*  (*Foo3)(char* st);
    }
    MyVirtualInterface;
      
  這樣假設我們在主體框架中要使用橋模式。(我們的主類是DoMyAct,接口具體實現類是Act1,Act2)下面我將依次介紹這些“類”。(C中的“類”在前面有說明,這里換了一個,是使用早期的數組的辦法)
 
  主類DoMyAct: 主類中含有MyVirtualInterface* m_pInterface; 主類有下函數:

    DoMyAct_SetInterface(MyVirtualInterface* pInterface)
    {
        m_pInterface= pInterface;
    }
    DoMyAct_Do()
    {
        if(m_pInterface==NULL) return;
        m_pInterface->Foo1();
        c=m_pInterface->Foo2();
    }

  子類Act1:實現虛結構,含有MyVirtualInterface  st[MAX]; 有以下函數:

    MyVirtualInterface* Act1_CreatInterface()
    {
        index=FindValid() //對象池或者使用Malloc !應該留在外面申請,實例化
        if(index==-1) return NULL;
        St[index].Foo1=Act1_Foo1; // Act1_Foo1要在下面具體實現

        St[index].Foo2=Act1_Foo2;
        St[index].Foo3=Act1_Foo3;
        Return &st [index];
    }

  子類Act2同上。
 
  在main中,假設有一個對象List。List中存貯的是MyVirtualInterface指針,則有:

    if( (p= Act1_CreatInterface()) != NULL)
    List_AddObject(&List, p); //Add All
 
    While(p=List_GetObject()){
        DoMyAct_SetInterface(p);//使用Interface代替了原來大篇幅的Switch Case
        DoMyAct_Do();//不要理會具體的什么樣的動作,just do it
    }
 
    FREE ALL 更多文章 更多內容請看C/C++進階技術文檔專題,或    在微系統(tǒng)里面,比如嵌入式,通常使用對象池的技術,這個時候可以不用考慮釋放的問題(對象池預先沒有空間,使用Attach,在某個函數中申請一個數組并臨時為對象池分配空間,這樣函數結束,對象池就釋放了)
 
  但是在Pc環(huán)境下,由于程序規(guī)模比較大,更重要的是一些非凡的要求,使得對象的生命周期必須延續(xù)到申請的那個函數體以外,就不得不使用malloc,實際上即使在C++中,new對象的自動釋放始終是一個令人頭疼的問題,新的標準引入了智能指針。但是就我個人而言,我覺得將內存釋放的問題完全的交給機器是不可信任的,它只能達到準最佳。
 
  你知道設計java的垃圾回收算法有多困難嗎?現實世界是錯綜復雜的,在沒有先驗條件下,要想得到精確的結果及其困難。所以我說程序員要時刻將free記在心上,有關程序的健壯性和自我防御將在另外一篇文章中講述。
 
  3.純虛結構的退化

  下面我們來看看假如struct里面僅僅有一個函數是什么? 這個時候假如我們不使用struct,僅僅使用函數指針又是什么? 我們發(fā)現,這樣就退化為普通的函數指針的使用了。
 
  所以說,有的時候我覺得面向對象僅僅是一種形式,而不是一種技術。是一種觀點,而不是一種算法。但是,正如炭,石墨和鉆石的關系一樣,雖然分子式都是C,但是組成方法不一樣,表現就完全不一樣了!

  有的時候,我們經常被編程中瑣碎的事情所煩惱,而偏離了重心,其實程序可進化的特性是很重要的。有可能,第一次是不成功的,但是只要可進化,就可以發(fā)展。
 
  4.進階――類結構樹,父類不是純虛類的類

  前面僅僅講的是父類是純虛結構的情況 (面向對象建議的是所有類的基類都是從純虛類開始的), 那么當類層次比較多的情況下,出現父類不是純虛結構怎么辦呢。嘿嘿,其實在C中的實現比C++要簡單多了。因為C中各個函數是分散的。
 
  在這里使用宏定義是一個很好的辦法:比如兩個類Act1,ActByOther1“繼續(xù)”Act1:

    MyVirtualInterface* ActByOther1_CreatInterface()
    {
        index=FindValid() //對象池或者使用Malloc
        if(index==-1) return NULL;
        St[index].Foo1= ActByOther1_Foo1; // Act1_Foo1要在下面具體實現
        St[index].Foo2= ActByOther1_Foo2;
        St[index].Foo3= ActByOther1_Foo3;
        Return &st [index];

    }
 
    #define ActByOther1_Foo1 Act1_Foo1  //這就是繼續(xù) 嘿嘿
    ActByOther1_Foo2(){}                    //  可以修改其實現
    ActByOther1_DoByOther() {}         //當然就可以添加新的實現咯
 
  5.實例――可以參見H264的源碼,其中NalTool就是這樣的一個純虛結構。 更多文章 更多內容請看C/C++進階技術文檔專題,或

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 盘锦市| 稷山县| 邢台县| 淄博市| 贡觉县| 南充市| 竹山县| 册亨县| 九江县| 临猗县| 咸丰县| 称多县| 荣昌县| 玉溪市| 包头市| 新民市| 迁安市| 页游| 镇坪县| 米林县| 城口县| 辽阳市| 赤壁市| 武宁县| 台山市| 娱乐| 贵港市| 玉田县| 神池县| 巩义市| 奇台县| 额济纳旗| 宁乡县| 定安县| 自治县| 定西市| 东莞市| 嵊州市| 襄垣县| 青川县| 墨脱县|