欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
OO in C(2): C語(yǔ)言的多態(tài)實(shí)現
相信很多人都看過(guò)設計模式方面的書(shū),大家有什么體會(huì )呢?Bridge,Proxy,Factory這些設計模式都是基于抽象類(lèi)的。使用抽象對象是這里的一個(gè)核心。
   
    其實(shí)我覺(jué)得框架化編程的一個(gè)核心問(wèn)題是抽象,用抽象的對象構建程序的主體框架,這是面向對象編程的普遍思想。用抽象構建骨架,再加上多態(tài)就形成了一個(gè)完整的程序。由于C++語(yǔ)言本身實(shí)現了繼承和多態(tài),使用這樣的編程理念(理念啥意思?跟個(gè)風(fēng),嘿嘿)在C++中是十分普遍的現象,可以說(shuō)Virtual(多態(tài))是VC的靈魂。

    但是,使用C語(yǔ)言的我們都快把這個(gè)多態(tài)忘光光了。我常聽(tīng)見(jiàn)前輩說(shuō),類(lèi)?多態(tài)?我們用的是C,把這些忘了吧。很不幸的是,我是一個(gè)固執的人。這么好的東西,為啥不用呢。很高興的,在最近的一些純C代碼中,我看見(jiàn)了C中的多態(tài)!下面且聽(tīng)我慢慢道來(lái)。

1.       VC中的Interface是什么
    Interface:中文解釋是接口,其實(shí)它表示的是一個(gè)純虛類(lèi)。不過(guò)我所要說(shuō)的是,在VC中的Interface其實(shí)就是struct,查找Interface的定義,你可以發(fā)現有這樣的宏定義:
    #Ifndef Interface
        #define Interface struct
    #endif
而且,實(shí)際上在VC中,如果一個(gè)類(lèi)有Virtual的函數,則類(lèi)里面會(huì )有vtable,它實(shí)際上是一個(gè)虛函數列表。實(shí)際上C++是從C發(fā)展而來(lái)的,它不過(guò)是在語(yǔ)言級別上支持了很多新功能,在C語(yǔ)言中,我們也可以使用這樣的功能,前提是我們不得不自己實(shí)現。

2.C中如何實(shí)現純虛類(lèi)(我稱(chēng)它為純虛結構)
    比較前面,相信大家已經(jīng)豁然開(kāi)朗了。使用struct組合函數指針就可以實(shí)現純虛類(lèi)。
例子: typedef struct {
              void (*Foo1)();
              char (*Foo2)();
              char* (*Foo3)(char* st);
        }MyVirtualInterface;
   
    這樣假設我們在主體框架中要使用橋模式。(我們的主類(lèi)是DoMyAct,接口具體實(shí)現類(lèi)是Act1,Act2)下面我將依次介紹這些“類(lèi)”。(C中的“類(lèi)”在前面有說(shuō)明,這里換了一個(gè),是使用早期的數組的辦法)

主類(lèi)DoMyAct: 主類(lèi)中含有MyVirtualInterface* m_pInterface; 主類(lèi)有下函數:
                  DoMyAct_SetInterface(MyVirtualInterface* pInterface)
                  {
                      m_pInterface= pInterface;
                  }
                  DoMyAct_Do()
                  {
                      if(m_pInterface==NULL) return;
                      m_pInterface->Foo1();
                      c=m_pInterface->Foo2();
                  }
子類(lèi)Act1:實(shí)現虛結構,含有MyVirtualInterface st[MAX]; 有以下函數:
            MyVirtualInterface* Act1_CreatInterface()
              {
                  index=FindValid() //對象池或者使用Malloc !應該留在外面申請,實(shí)例化
                  if(index==-1) return NULL;
                  St[index].Foo1=Act1_Foo1; // Act1_Foo1要在下面具體實(shí)現
                  St[index].Foo2=Act1_Foo2;
                  St[index].Foo3=Act1_Foo3;
                  Return &st [index];
              }
子類(lèi)Act2同上。

在main中,假設有一個(gè)對象List。List中存貯的是MyVirtualInterface指針,則有:
    if( (p= Act1_CreatInterface()) != NULL)
    List_AddObject(&List, p); //Add All

    While(p=List_GetObject()){
        DoMyAct_SetInterface(p);//使用Interface代替了原來(lái)大篇幅的Switch Case
        DoMyAct_Do();//不要理會(huì )具體的什么樣的動(dòng)作,just do it
    }

    FREE ALL。
    在微系統里面,比如嵌入式,通常使用對象池的技術(shù),這個(gè)時(shí)候可以不用考慮釋放的問(wèn)題(對象池預先沒(méi)有空間,使用Attach,在某個(gè)函數中申請一個(gè)數組并臨時(shí)為對象池分配空間,這樣函數結束,對象池就釋放了)

    但是在Pc環(huán)境下,由于程序規模比較大,更重要的是一些特殊的要求,使得對象的生命周期必須延續到申請的那個(gè)函數體以外,就不得不使用malloc,實(shí)際上即使在C++中,new對象的自動(dòng)釋放始終是一個(gè)令人頭疼的問(wèn)題,新的標準引入了智能指針。但是就我個(gè)人而言,我覺(jué)得將內存釋放的問(wèn)題完全的交給機器是不可信任的,它只能達到準最佳。

    你知道設計Java的垃圾回收算法有多困難嗎?現實(shí)世界是錯綜復雜的,在沒(méi)有先驗條件下,要想得到精確的結果及其困難。所以我說(shuō)程序員要時(shí)刻將free記在心上,有關(guān)程序的健壯性和自我防御將在另外一篇文章中講述。

3.純虛結構的退化
    下面我們來(lái)看看如果struct里面僅僅有一個(gè)函數是什么? 這個(gè)時(shí)候如果我們不使用struct,僅僅使用函數指針又是什么? 我們發(fā)現,這樣就退化為普通的函數指針的使用了。

    所以說(shuō),有的時(shí)候我覺(jué)得面向對象僅僅是一種形式,而不是一種技術(shù)。是一種觀(guān)點(diǎn),而不是一種算法。但是,正如炭,石墨和鉆石的關(guān)系一樣,雖然分子式都是C,但是組成方法不一樣,表現就完全不一樣了!
    有的時(shí)候,我們經(jīng)常被編程中瑣碎的事情所煩惱,而偏離了重心,其實(shí)程序可進(jìn)化的特性是很重要的。有可能,第一次是不成功的,但是只要可進(jìn)化,就可以發(fā)展。

4.進(jìn)階――類(lèi)結構樹(shù),父類(lèi)不是純虛類(lèi)的類(lèi)
    前面僅僅講的是父類(lèi)是純虛結構的情況 (面向對象建議的是所有類(lèi)的基類(lèi)都是從純虛類(lèi)開(kāi)始的), 那么當類(lèi)層次比較多的情況下,出現父類(lèi)不是純虛結構怎么辦呢。嘿嘿,其實(shí)在C中的實(shí)現比C++要簡(jiǎn)單多了。因為C中各個(gè)函數是分散的。

在這里使用宏定義是一個(gè)很好的辦法:比如兩個(gè)類(lèi)Act1,ActByOther1“繼承”Act1:
            MyVirtualInterface* ActByOther1_CreatInterface()
              {
                  index=FindValid() //對象池或者使用Malloc
                  if(index==-1) return NULL;
                  St[index].Foo1= ActByOther1_Foo1; // Act1_Foo1要在下面具體實(shí)現
                  St[index].Foo2= ActByOther1_Foo2;
                  St[index].Foo3= ActByOther1_Foo3;
                  Return &st [index];
              }

    #define ActByOther1_Foo1 Act1_Foo1 //這就是繼承 嘿嘿
    ActByOther1_Foo2(){}             // 可以修改其實(shí)現
  ActByOther1_DoByOther() {}       //當然就可以添加新的實(shí)現咯

5.實(shí)例――可以參見(jiàn)H264的源碼,其中NalTool就是這樣的一個(gè)純虛結構。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
luajit FFI LUA腳本中怎樣調用C自己定義的函數
Linux環(huán)境進(jìn)程間通信(二): 信號(下)
再談typedef(重點(diǎn)為函數指針)
C標準庫函數淺析
編程語(yǔ)言 Google Go 的初級讀本 - 開(kāi)源中國社區
C語(yǔ)言面向對象編程范式
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久