OO in C(2): C語言的多態實現

來源:互聯網
上載者:User
C語言的多態實現       相信很多人都看過設計模式方面的書,大家有什麼體會呢?Bridge,Proxy,Factory這些設計模式都是基於抽象類別的。使用抽象對象是這裡的一個核心。              其實我覺得架構化編程的一個核心問題是抽象,用抽象的對象構建程式的主體架構,這是物件導向編程的普遍思想。用抽象構建骨架,再加上多態就形成了一個完整的程式。由於C++語言本身實現了繼承和多態,使用這樣的編程理念(理念啥意思?跟個風,嘿嘿)在C++中是十分普遍的現象,可以說Virtual(多態)是VC的靈魂。        但是,使用C語言的我們都快把這個多態忘光光了。我常聽見前輩說,類?多態?我們用的是C,把這些忘了吧。很不幸的是,我是一個固執的人。這麼好的東西,為啥不用呢。很高興的,在最近的一些純C代碼中,我看見了C中的多態!下面且聽我慢慢道來。 1.         VC中的Interface是什麼       Interface:中文解釋是介面,其實它表示的是一個純虛類。不過我所要說的是,在VC中的Interface其實就是struct,尋找Interface的定義,你可以發現有這樣的宏定義:       #Ifndef Interface              #define Interface struct       #endif而且,實際上在VC中,如果一個類有Virtual的函數,則類裡面會有vtable,它實際上是一個虛函數列表。實際上C++是從C發展而來的,它不過是在語言層級上支援了很多新功能,在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。       在微系統裡面,比如嵌入式,通常使用對象池的技術,這個時候可以不用考慮釋放的問題(對象池預先沒有空間,使用Attach,在某個函數中申請一個數組並臨時為對象池分配空間,這樣函數結束,對象池就釋放了)        但是在Pc環境下,由於程式規模比較大,更重要的是一些特殊的要求,使得對象的生命週期必須延續到申請的那個函數體以外,就不得不使用malloc,實際上即使在C++中,new對象的自動釋放始終是一個令人頭疼的問題,新的標準引入了智能指標。但是就我個人而言,我覺得將記憶體釋放的問題完全的交給機器是不可信任的,它只能達到准最佳。        你知道設計Java的記憶體回收演算法有多困難嗎?現實世界是錯綜複雜的,在沒有先驗條件下,要想得到精確的結果及其困難。所以我說程式員要時刻將free記在心上,有關程式的健壯性和自我防禦將在另外一篇文章中講述。 3.純虛結構的退化       下面我們來看看如果struct裡面僅僅有一個函數是什嗎? 這個時候如果我們不使用struct,僅僅使用函數指標又是什嗎? 我們發現,這樣就退化為普通的函數指標的使用了。        所以說,有的時候我覺得物件導向僅僅是一種形式,而不是一種技術。是一種觀點,而不是一種演算法。但是,正如炭,石墨和鑽石的關係一樣,雖然分子式都是C,但是組成方法不一樣,表現就完全不一樣了!       有的時候,我們經常被編程中瑣碎的事情所煩惱,而偏離了重心,其實程式可進化的特性是很重要的。有可能,第一次是不成功的,但是只要可進化,就可以發展。 4.進階――類結構樹,父類不是純虛類的類       前面僅僅講的是父類是純虛結構的情況 (物件導向建議的是所有類的基類都是從純虛類開始的), 那麼當類層次比較多的情況下,出現父類不是純虛結構怎麼辦呢。嘿嘿,其實在C中的實現比C++要簡單多了。因為C中各個函數是分散的。 在這裡使用宏定義是一個很好的辦法:比如兩個類Act1,ActByOther1“繼承”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  //這就是繼承 嘿嘿       ActByOther1_Foo2(){}                    //  可以修改其實現    ActByOther1_DoByOther() {}         //當然就可以添加新的實現咯 

5.執行個體――可以參見H264的源碼,其中NalTool就是這樣的一個純虛結構。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.