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);
}
至于像方法之类的东西,自然还是用函数指针来模拟,
为了在嵌入式系统上使用方便,不再用宏来定义