lw_oopc(C語言的面向對象)


    面向對象這個概念和C語言似乎是無緣的,但如果你真的很想用怎么辦?幸運的是有人和你的想法一樣,並且做出了實實在在的東西。我了解的比較多的是lw_oopc和ooc兩個東東。

    ooc全稱objective oriented c,作者做了大量的工作實現了c語言的封裝、多態、繼承這三種面向對象特征,還實現了所謂的虛函數。老實說,我對ooc的作者佩服的五體投地,能把c語言玩到這個程度非常了得了。ooc的文檔工作做的也不錯,但看了它的doc之后,還是覺得用起來有些麻煩。於是,又去google之,最終找到lw_oopc這個好東東。

    lw_oopc僅用了2個文件,.h及.c文件就實現了面向對象的三大因素,實現過程極為簡潔又富含技巧。lw_oopc說白了,就是定義了一堆宏,使用起來也就是調用這些宏。

//| INTERFACE | 接口 //---------------------------------------------------------------------- //| CLASS | 類 //---------------------------------------------------------------------- //| CTOR | 構造器開始 //---------------------------------------------------------------------- //| END_CTOR | 構造器截止 //---------------------------------------------------------------------- //| FUNCTION_SETTING | 關聯成員函數指針 //---------------------------------------------------------------------- //| IMPLEMENTS | 繼承 //----------------------------------------------------------------------
//| DTOR | 為了支持析構函數的概念 
//| END_DTOR | 
//---------------------------------------------------------------------- //| ABS_CLASS | 為了支持抽象類的概念 
//---------------------------------------------------------------------- //| ABS_CTOR | 為了支持可繼承的抽象類的構造函數 
//| END_ABS_CTOR | 
//---------------------------------------------------------------------- //| EXTENDS | 為了讓熟悉Java的人容易理解(與IMPLEMENTS宏等同) 
//---------------------------------------------------------------------- //| SUPER_CTOR | 為了支持子類調用父類的構造函數 
//---------------------------------------------------------------------- //| SUPER_PTR | 為了支持向上轉型 
//| SUPER_PTR_2 | 
//| SUPER_PTR_3 | 
//---------------------------------------------------------------------- //| SUB_PTR | 為了支持向下轉型 
//| SUB_PTR_2 | 
//| SUB_PTR_3 | 
//---------------------------------------------------------------------- //| INHERIT_FROM | 為了支持訪問直接父類的數據成員 
//----------------------------------------------------------------------

 

還是先以一個簡單的例子入手,看看用lw_oopc做一個‘類’是怎樣的。

————————————————————————————————————————————

設計一個抽象類:Animal,屬性有:age,方法有:eat

繼承Animal,設計一個類:Dog,實現其方法

繼承Animal,設計一個類:Bird,增加方法:Fly

代碼如下所示:

***********************************************************
#include <stdio.h>
#include "lw_oopc.h"

********************************
/* Animal */
ABS_CLASS(Animal)
{
    int age;
    
    void (*Init)(Animal*);
    void (*Eat)(Animal*);
};

static void Animal_Init(Animal* me)
{
    me->age = 0;
}

static void Animal_Eat(Animal* me)
{
    printf("Animal eat.\r\n");
}

ABS_CTOR(Animal)
FUNCTION_SETTING(Init, Animal_Init);
FUNCTION_SETTING(Eat, Animal_Eat);
END_ABS_CTOR

********************************
/* Dog */
CLASS(Dog)
{
    EXTENDS(Animal);
    
    void (*Init)(Dog*);
};

static void Dog_Init(Dog* me)
{
    SUPER_PTR(me, Animal)->Init(SUPER_PTR(me, Animal));
}

static void Dog_Eat(Animal* me)
{
    printf("Dog eat.\r\n");
}

CTOR(Dog)
SUPER_CTOR(Animal);
FUNCTION_SETTING(Init, Dog_Init);
FUNCTION_SETTING(Animal.Eat, Dog_Eat);
END_CTOR

********************************
/* Bird */
CLASS(Bird)
{
    EXTENDS(Bird);
    
    void (*Init)(Bird*);
    void (*Fly)(Bird*);
};

static void Bird_Init(Bird* me)
{
    SUPER_PTR(me, Animal)->Init(SUPER_PTR(me, Animal));
}

static void Bird_Fly(Bird* me)
{
    printf("Bird fly.\r\n");
}

static void Bird_Eat(Animal* me)
{
    printf("Bird eat.\r\n");
}

CTOR(Bird)
SUPER_CTOR(Animal);
FUNCTION_SETTING(Init, Bird_Init);
FUNCTION_SETTING(Animal.Eat, Bird_Eat);
FUNCTION_SETTING(Fly, Bird_Fly);
END_CTOR

 

    有了這些定義,用起來就跟簡單c++的類一樣了,只是定義一個類的實例時應采用如下一種格式:

Dog* dog = Dog_new();
dog->Init(dog);

調用自身的方法:

Bird* bird = Bird_new();
bird->Init(bird);
bird->Fly(bird);

調用繼承的方法稍顯麻煩:

((Animal*)bird)->Eat((Animal*)bird);

或者當EXTENDS語句在定義類時並不在第一句(下一篇將揭露各個宏的真實面目)時,最穩妥也顯得繁瑣一點的方式為:

SUPER_PTR(bird, Animal)->Eat(SUPER_PTR(bird, Animal));

    是不是有那么點意思,抽象、繼承、多態幾個概念都包含了。同樣能看出,用了lw_oopc后並沒有減少你的代碼量,而是增加了不少。但用它的目的並非是減少體力輸出,而是對軟件結構的一種改良。

    各個宏的真實面目留待下一篇揭露。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM