C语言面向对象的简便方法

时间:2022-12-18 12:24:02

都知道C语言是面向过程的,但是现在软件规模越来越大,通过面向对象的方式可以简化开发。业余时间想了个简单的方法,在C中使用一部分面向对象的基本功能。由于C语言自身的限制,并不完善,只能将就用,聊胜于无,如果大家有好的想法可以一起讨论。

 

首先还是老规矩上代码: http://files.cnblogs.com/GhostZCH/object.rar

 

面向对象有三个基本属性:封装、继承和多态。 此处一一讲解处理方法。

 

1. 封装,基本思想就是用结构体代替类,属性没什么好说的,方法就麻烦点只能用函数指针了,基本思想和JS差不多,“函数就是对象的一个属性”。 缺点试试无法控制访问的私有和公用。由于C没有this指针,只好在每个函数都增加一个void*的参数将自己传进去。

 

 1  /* ********************************************************************** */
 2  /*          object    基类                                                */
 3  /* ********************************************************************** */
 4 
 5 
 6 typedef  struct stObj OBJECT_STRU;
 7 
 8 typedef  char* (*ToString_PF)( void *pObj,  char *pcStrBuf);
 9 typedef unsigned  int ClassID;
10 
11  struct stObj
12 {
13     ClassID m_uiCID;
14     ToString_PF pfToString;
15 };
16 
17  char* OBJ_ToString( void *pObj,  char *pcStrBuf)
18 {
19     sprintf(pcStrBuf,  " ClassName:%s;ClassID:%06u "" Object ", ((OBJECT_STRU *)pObj)->m_uiCID);
20      return pcStrBuf;
21 }
22 
23 OBJECT_STRU *new_Object()
24 {
25     OBJECT_STRU* pstObj = (OBJECT_STRU*)malloc( sizeof(OBJECT_STRU));
26 
27      if ( NULL == pstObj )
28     {
29          return NULL;
30     }
31 
32     pstObj->m_uiCID = CID_OBJ;
33     pstObj->pfToString = OBJ_ToString;
34 
35      return pstObj;

36 } 

 

  2继承:继承的方法是用类似组合的方式,将父类结构体作为子类的第一个属性,注意,这里必须是第一个,这样后面的强制类型转换才会有效。通过强制转换转换成父类。

 

  1 /************************************************************************/

 2  /*          animal    子类一                                              */
 3  /* ********************************************************************** */
 4 
 5 typedef  struct stAnimal
 6 {
 7      //  父类实体,必须放在第一个,强制转换才有效,利用这种方法产生继承的效果
 8      OBJECT_STRU m_stBaseObj; 
 9 
10      //  新增属性
11       char acName[NAME_LEN];  
12     
13      //  也可增加新增方法
14       //  int (* pfGetAge)();
15  }ANIMAL_STRU;
16 
17  //  覆盖父类方法
18  char* ANM_ToString( void *pObj,  char *pcStrBuf)
19 {
20     sprintf(pcStrBuf,  " Classname:%s; AnimalName:%s; ClassID:%06u "
21          " Animal "
22         ((ANIMAL_STRU *)pObj)->acName,
23         ((ANIMAL_STRU *)pObj)->m_stBaseObj.m_uiCID);
24      return pcStrBuf;
25 }
26 
27 ANIMAL_STRU *new_Animal()
28 {
29     ANIMAL_STRU* pstObj = (ANIMAL_STRU*)malloc( sizeof(ANIMAL_STRU));
30     
31      if ( NULL == pstObj )
32     {
33          return NULL;
34     }
35     
36     pstObj->m_stBaseObj.m_uiCID = CID_ANM;
37     pstObj->m_stBaseObj.pfToString = ANM_ToString;  //  覆盖父类方法,产生多态效果
38      pstObj->acName[ 0] =  ' \0 ';
39     
40      return pstObj;
41 }
42 

 

 三,多态,通过挂载不同的函数指针实现

 1 ==========
 2 
 3  /* ********************************************************************** */
 4  /*          测试                                                          */
 5  /* ********************************************************************** */
 6 
 7  int main()
 8 {
 9      char acStrBuf[ 200] = { 0};
10 
11     OBJECT_STRU *pObj = NULL;
12     ANIMAL_STRU *pAnm = NULL;
13     PLANT_STRU  *pPlt = NULL;
14 
15      //  定义父类
16      OBJECT_STRU *pObj_animal = NULL;
17     OBJECT_STRU *pObj_plant  = NULL;
18 
19      //  父类函数和属性调用
20      pObj = new_Object();
21     printf( " [ID = %u][ ToString = %s ]\n ", pObj->m_uiCID, pObj->pfToString(pObj, acStrBuf) );
22     free(pObj);
23     pObj = NULL;
24    
25      //  子类函数和属性调用
26      pAnm = new_Animal();
27     strcpy(pAnm->acName, " Panda ");
28     printf( " %s\n ", pAnm->m_stBaseObj.pfToString(pAnm, acStrBuf) );
29     free(pPlt);
30     free(pAnm);
31     pPlt = NULL;
32     pAnm = NULL;
33 
34      //  子类函数和属性调用
35      pPlt = new_Plant();
36     strcpy(pPlt->acName, " Tree ");
37     printf( " %s\n ", pPlt->m_stBaseObj.pfToString(pPlt, acStrBuf) );
38 
39 
40      /* ********************************************************************** */
41      /*   多态测试                                                             */
42      /* ********************************************************************** */
43 
44      //  定义父类
45       //  OBJECT_STRU *pObj_animal = NULL;
46       //  OBJECT_STRU *pObj_plant  = NULL;
47 
48       //  初始化子类
49      pObj_animal = (OBJECT_STRU *)new_Animal();
50     pObj_plant  = (OBJECT_STRU *)new_Plant();
51 
52      //  执行相同的函数产生不同的效果
53      printf( " %s\n ", pObj_animal->pfToString(pObj_animal, acStrBuf) );
54     printf( " %s\n ",  pObj_plant->pfToString(pObj_plant , acStrBuf) );
55 
56     getchar();
57 
58     free(pObj_animal);
59     free(pObj_plant );
60 
61      return  0;
62 }
63