OOC-GCC基本结构图[0.6][终于有时间整点相关的文档了]
OOC-GCC特性介绍与使用说明

Hello,OOC World![Chap2Sec1-3][GFDL]

pingf posted @ Sat, 28 May 2011 20:24:56 -1100 in 未分类 , 2756 readers

项目地址(点击超链) OOC_GCC 

注意:OOC_GCC 源码以LGPL发布,文档为GFDL,文档相关测试用例为GPL3

Web版文档发布暂定为项目托管地SVN仓库,WikiPage,"这里",以及我的博客.

转载请注明出处


Hello,OOC World!


                ---- 原始作者: 大孟  pingf0@gmail.com


                                          崇 尚 开 源 , 热 爱 分 享 !  


这份Tutorial性质的文档其实很扯的,非要啰嗦些用C语言进行面向对象开发的基本内容

 

版权说明

License Type: GFDL

Copyright (C) 2011-2011 Jesse Meng  pingf0@gmail.com
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation;with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.A copy of the license is included in the section entitled “GNU Free Documentation License”.

OOC-GCC为开源软件,遵循LGPL3协议发布,本手册为相关配套文档,采用GFDL协议发布,本手册中提供的相关示例代码以及简化版的OOC-LITE 需遵循GPL3协议.任何使用请遵循相关协议, 如有和协议相冲突的特殊要求, 请联系我[ pingf0@gmail.com ]

第二章 { 伸展运动 }

 

 


 

1. < CLASS,CTOR,DTOR >

宏是一个十分强大的特性,某些人的观点是通过宏实际上我们可以创立一个新的语言!当然个人认为只是形式上罢了.不过通过宏,代码看起来真的可以很简洁,很强大.比如下面所介绍的,将用一些简单的宏让C代码看上去有点C++的味道.


#include "OOC.h"
CLASS(A){
        int a;
        void (*showA)(A *);
};
static void A_showA(A *THIS){
        printf("the value of obj's a is %d\n",THIS->a);
}
CTOR(A){
        THIS->a=100;
        THIS->showA=A_showA;
}
DTOR(A){
        THIS->a=0;
        THIS->showA=NULL;
}
int main(){
        A * obj=newA();
        obj->showA(obj);
        delA(&obj);
        return 0;
}

这个例子中用到了三个宏,分别是CLASS,CTOR(对应CONSTRUCTOR),DTOR(对应DESTRUCTOR). 如果把他们展开,其实和前面"对称之美"一节中的代码是一样的.但又不一样,因为使用了宏,可读性大大提高, 而代码量大大减少(上面的代码和上一章中的对比减少了约1/3)!这只是一个简单的类的模拟,如果类比较多且继生关系比较复杂, 那么节省的代码量还是相当可观的.

 

不过这里还是要再次强调一下,宏是好东西,但如果滥用反而会使可读性大大降低,难懂不说,还不利于以后的维护.

关于本手册中的宏的设计,我尽量做到简单明了,易于记忆.

 

闲话少扯,现在具体来看一下CLASS,CTOR和DTOR宏具体是怎么实现的.

#include <stdio.h>
#include <stdlib.h>
#define CLASS(Type) \
typedef struct _##Type Type; \
void ini##Type(struct _##Type *); \
void fin##Type(struct _##Type *); \
Type * new##Type(); \
void del##Type(struct _##Type **); \
struct _##Type

#define CTOR(Type) \
Type * new##Type() { \
    Type *THIS; \
    THIS=(Type*)calloc(1,sizeof(Type)); \
    if( NULL==THIS ) { \
        return NULL; \
    } \
    ini##Type(THIS); \
    return THIS; \
} \
void ini##Type(Type * THIS)

#define DTOR(Type) \
void del##Type(Type **THIS) { \
    fin##Type(*(THIS)); \
    free(*(THIS)); \
    (*(THIS))=NULL; \
} \
void fin##Type(Type *THIS)

没错,就是这么简单!(当然如果你觉得这都算复杂了话,还是不要继续下面的文字了,这是我目前能做到的最简化的宏了)

下一节将会闲扯一些为什么这样设计,以及仅仅是这样还有那些不足.

 

2. < 从CLASS说起 >

 

C语言中直接使用结构体其实是件很麻烦的事,因为每次声明都要使用额外的"struct"来声明.一些初学C的人,特别从VC开始入门那些,总会分不清什么是C,什么是C++.特别是在struct声明这一块也特别容易按照懒省事儿的方法来写.但是我们应该知道一些事情----真正的纯C编译器如果不事先typedef一下是无法声明一个自定的结构体的实例的.

下面看一小段代码,演示如何将typedef与struct来结合.

typedef struct {int a;} A;
int main(){
        A obj;
        ojb.a=1;
        return 0;
}

关于typedef的语法,如果不牵扯结构体,是比较好理解的,比如"typedef int bool;"就是将原有的int型重定义为一个全新的bool型,尽管本质上它们是一样的.而一旦与结构体结合,就略微有些绕了.为了简化说明它的语法,上面的代码我做了一些处理,一是结构体本身匿名话,二是简化结构体内容并将其写到一行之内.这样我们看上去会十分明了还是"typedef struct ... A;"的形式,而"..."中我们其实定义了一个结构体的内容,只不过这个结构体本身是"匿名的".

更加常规的写法是,像下面这样.

typedef struct _A A;
struct _A{
        int a;
};
int main(){
        A obj;
        ojb.a=1;
        return 0;
}

CLASS宏中,也使用了和上面类似的做法来简化struct声明实例时的步骤.

#define CLASS(Type) \
typedef struct _##Type Type; \
void ini##Type(struct _##Type *); \
void fin##Type(struct _##Type *); \
Type * new##Type(); \
void del##Type(struct _##Type **); \
struct _##Type

CLASS宏不但简化了struct声明实例的工作,还声明了"四大函数"(将函数声明放在最前面是有好处的,它会让编译器在一开始就知道有这么些类型的函数).这四个函数其实是"两队",一对是ini和fin打头,另一对是new和del打头.其分别对应栈内存和堆内存上实例的构造与析构.

而CLASS宏的最后则是一个全开放的形式(这里的全开放是指某个宏不需要语气配合相对应的"截止"宏来保护一段代码),开头和结尾都是用C语言自身的"{"和"}"符合来指明.

在下一节,将会介绍用于构造和析构的CTOR和DTOR宏,而它们则封装了"四大函数"的具体实现.

 

3. < CTOR & DTOR >

这一节来说一下用于模拟构造函数的宏CTOR以及用于模拟析构函数的宏DTOR.先回顾下CTOR的定义.

#define CTOR(Type) \
Type * new##Type() { \
    Type *THIS; \
    THIS=(Type*)calloc(1,sizeof(Type)); \
    if( NULL==THIS ) { \
        return NULL; \
    } \
    ini##Type(THIS); \
    return THIS; \
} \
void ini##Type(Type * THIS)

假设我们还是要定义一个名为"A"的类,那么上面的代码中我们要把"Type"换成"A",并删除"##"(注意##在宏的使用中表示"连结").这样的话,我们就看到了一个完整的"newA"函数和一个没有写完的"iniA"函数(请参考上一节最后的"四大函数"一说).

"iniA"函数实际上是真正的构造函数,其负责一个"类"成员的初始化.但其没有写完,因为具体如何初始化是由我们自己说了算的,我们可以在其后面紧跟着写上"{ THIS->a=1; }"(假设A类中有int型成员变量a),这样就完成了一个简单的构造函数的实现.

我们要注意的是iniA函数要接受一个类实例指针,然后再对其进行初始化.也就是说这个函数本身是不涉及内存的分配的,我们可以传入一个指向栈内存的指针,也可以传入一个指向堆内存的指针,它都会对其进行"初始化"!但是如果我们使用堆内存,还要先定义一个指针,并指向一块malloc返回的内存再传入ini函数,这多少有些麻烦.为了方便的使用堆内存,上面的CTOR宏还给出了一个new函数,这里仍以一个名为"A"的类为例.newA就将malloc函数和iniA函数和二为一!我们使用的时候只需像"A * obj=newA();"这样即可,这大大方便了堆实例的使用!

不难发现,newA就是对iniA的一个简单封装,其做的工作就是"1.分配堆内存.2.调用ini函数.3.返回一个指向已分配内存的指针."这三块工作,这是有章可循的.也正因此,我们将其完全封装在CTOR宏之中.使用的时候我们几乎感觉不到它的存在,直接new就好.

下面再来看一下用于析构的DTOR宏,

#define DTOR(Type) \
void del##Type(Type **THIS) { \
    fin##Type(*(THIS)); \
    free(*(THIS)); \
    (*(THIS))=NULL; \
} \
void fin##Type(Type *THIS)

这里面定义了"四大函数"中用于析构的del函数和fin函数.其分别对应着前面的new函数和ini函数.我们可以对比着前面的讲述来理解.ini函数是真正的构造函数,fin函数是真正的析构函数.new是ini函数的一个封装,其做的具体工作就是先malloc在ini,del则是fin函数的一个封装,其做的具体工作是先fin再free.

当然因为有了new函数和del函数这样针对堆内存的封装,ini函数和fin函数更多的时候是与栈内存来配合使用的.

总的来看CTOR宏和DTOR宏,将涉及内存分配的部分独立出来可谓好处多多,不但可以更加自由且明确的使用栈内存和堆内存,还使得用于构造和析构的宏也能保持和前面CLASS宏一样的"全开放性",同时CTOR宏和DTOR宏几乎是完全对称的,这意味着我们只需理解一半,另一半就迎刃而解了.

 

despacito lyrics said:
Fri, 10 Nov 2017 20:27:46 -1100

The information you share is very useful. It is closely related to my work and has helped me grow. Thank you!

meidir said:
Mon, 29 Aug 2022 04:20:05 -1100

Ordinary comes to visit and listed below are one way to thanks for your time for one's exertion, which inturn means that So i'm seeing this website every single day, hunting for unique, important tips. A number of, many thanks! 補光燈

 

==================

 

Seriously sturdy, magnificent, fact-filled information and facts listed here. A person's discussions Never need disappoint, and the unquestionably is valid listed here in addition. You actually continually make a fun learn. Do you convey to I'm just happy?: )#) Keep up to date the nice reports. 雲台

 

==================

 

It is a fantastic write-up, Thank you regarding offering myself these records. Retain submitting. 電腦回收

 

=====================

 

With thanks to get furnishing recently available posts in connection with the dilemma, I actually look ahead to learn extra. Macbook回收

NCERT Urdu Question said:
Sat, 24 Sep 2022 20:17:14 -1100

Every student of Secondary education can download NCERT STD-10 Urdu Sample Paper 2023 with sample answers to gain high score by knowing the new exam scheme or question paper style for all exams such as SA1, SA2, FA1, FA2, FA3, FA4 and Assignments held under Term-1 & Term-2 of the course. The NCERT have introduced subject wide study & learning material for all regional students of the country. NCERT Urdu Question Paper Class 10 Every student of Secondary education can download NCERT STD-10 Urdu Sample Paper 2023 with sample answers to gain high score by knowing the new exam scheme or question paper style for all exams such as SA1, SA2, FA1, FA2, FA3, FA4.


Login *


loading captcha image...
(type the code from the image)
or Ctrl+Enter