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.
");
}

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.
");
}

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.
");
}

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

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后并没有减少你的代码量,而是增加了不少。但用它的目的并非是减少体力输出,而是对软件结构的一种改良。

    各个宏的真实面目留待下一篇揭露。

原文地址:https://www.cnblogs.com/robert-cai/p/3456785.html