C语言模拟OO机制的再研究
Posted on Fri, 27 Aug 2010 06:00:38 -1100因为过一段日子可能又要写些单片机上的代码,所以难免还是离不开C.
以前研究过GObject,也自己用宏写过一些模拟OO的东西,不过这些用在单片机上就不那么顺了.....
于是就想把OO的思想进一步简化,
最和新的东西无非就是类的声明(设计),构造与析构,
所以浓缩了下面的代码,并保证在Keil这类工具上0警告编译通过....
/** * OOC-Embeded [Jcoop elite version] * version : 0.2.0827elite * status : beta * author : Jesse Meng * Blog : http://www.pingf.me * E-mail : pingf0@gmail.com */ #ifndef __JC_OOP__ #define __JC_OOP__ #include <stdio.h> #include <stdlib.h> #ifdef BUILD_DLL /* DLL export */ #define EXPORT __declspec(dllexport) #elif defined BUILD_WITH_DLL /* EXE import */ #define EXPORT __declspec(dllimport) #else #define EXPORT #endif #define USE_HEAP_FOR_CLASS #ifdef USE_CALLOC_FOR_CLASS #define _CLASS_ALLOC(this,Type) \ this=(struct _##Type *)malloc(sizeof(struct _##Type)); #else #define _CLASS_ALLOC(this,Type) \ this=(struct _##Type *)calloc(1,sizeof(struct _##Type)); #endif ///////////////////////////////////////////////////////////// #ifdef USE_HEAP_FOR_CLASS #define _CLASS(Type) \ typedef struct _##Type Type; \ EXPORT int init##Type(struct _##Type * z); \ EXPORT int fin##Type(struct _##Type *z); \ EXPORT struct _##Type * new##Type(void); \ EXPORT int del##Type(struct _##Type **z); \ struct _##Type \ { // #define _END_CLASS }; ////////////////////////////////////// #define _CTOR(Type) \ EXPORT struct _##Type * new##Type(void) \ { \ struct _##Type *this; \ int initRet=0; \ _CLASS_ALLOC(this,Type); \ if( NULL==this ) { \ return NULL; \ } \ initRet=init##Type(this); \ if(initRet<0) { \ return NULL; \ } \ return this; \ } \ EXPORT int init##Type(struct _##Type * z) \ { \ struct _##Type * this=NULL;\ this=(struct _##Type *)z; \ if( NULL==this ) { \ return -1; \ } // #define _END_CTOR \ return 1; \ } // #define _DTOR(Type) \ EXPORT int del##Type(struct _##Type **z) \ { \ struct _##Type **this = NULL; \ int finRet=0; \ this=(struct _##Type **)z; \ if(NULL==this) { \ return -1; \ } \ finRet=fin##Type(*this); \ if(finRet<0) {\ return -1; \ } \ free(*this); \ (*this)=NULL; \ return 1; \ } \ EXPORT int fin##Type(struct _##Type *z) \ { \ struct _##Type * this=NULL; \ this=(struct _##Type *)z; \ if( NULL==this ) { \ return -1; \ } // #define _END_DTOR \ return 1; \ } #else #define _CLASS(Type) \ typedef struct _##Type Type; \ EXPORT int init##Type(struct _##Type * z); \ EXPORT int fin##Type(struct _##Type *z); \ struct _##Type \ { // #define _END_CLASS }; ////////////////////////////////////// #define _CTOR(Type) \ EXPORT int init##Type(struct _##Type * z) \ { \ struct _##Type * this=NULL;\ this=(struct _##Type *)z; \ if( NULL==this ) { \ return -1; \ } // #define _END_CTOR \ return 1; \ } // #define _DTOR(Type) \ EXPORT int fin##Type(struct _##Type *z) \ { \ struct _##Type * this=NULL; \ this=(struct _##Type *)z; \ if( NULL==this ) { \ return -1; \ } // #define _END_DTOR \ return 1; \ } #endif ///////////////////////////////////////////////////////////// #define CLASS(Type) _CLASS(Type) #define END_CLASS _END_CLASS // #define CTOR(Type) _CTOR(Type) #define END_CTOR _END_CTOR // #define DTOR(Type) _DTOR(Type) #define END_DTOR _END_DTOR // #endif
因为定义的东西少[也就100多行吧],所以使用起来就容易,省去了很多要记忆的东西,
下面是用例测试
#include <stdio.h> #include "jc_oop.h" CLASS(Test) int a; int b; END_CLASS CTOR(Test) printf("Test constructor"); //this->a=1; //this->b=2; END_CTOR // DTOR(Test) printf("Test destructor"); this->a=this->b=0; END_DTOR int main (int argc, char *argv[]) { Test stk; Test * heap=NULL; heap=newTest(); delTest(&heap); initTest(&stk); finTest(&stk); return(0); }
别看这么简单,但是像继承和组合的关系还是可以表示清楚的
比如下面测试了组合关系
#include <stdio.h> #include "jc_oop.h" CLASS(Test) int a; int b; END_CLASS CTOR(Test) printf("Test constructor\n"); //this->a=1; //this->b=2; END_CTOR // DTOR(Test) printf("Test destructor\n"); this->a=this->b=0; END_DTOR CLASS(Test2) Test *test; END_CLASS CTOR(Test2) printf("Test2 constructor\n"); this->test=newTest(); END_CTOR // DTOR(Test2) printf("Test2 destructor,actually this is after Test\n"); delTest(&(this->test)); END_DTOR int main (int argc, char *argv[]) { Test stk; Test2 * heap=NULL; heap=newTest2(); delTest2(&heap); return(0); }
至于像方法之类的东西,自然还是用函数指针来模拟,
为了在嵌入式系统上使用方便,不再用宏来定义