zoukankan      html  css  js  c++  java
  • C语言面向对象的简便方法

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

    首先还是老规矩上代码: https://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] = '';
    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 ] ", 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 ", 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 ", 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 ", pObj_animal->pfToString(pObj_animal, acStrBuf) );
    54     printf("%s ",  pObj_plant->pfToString(pObj_plant , acStrBuf) );
    55 
    56     getchar();
    57 
    58     free(pObj_animal);
    59     free(pObj_plant );
    60 
    61     return 0;
    62 }
    63 


  • 相关阅读:
    【cocos2d-js官方文档】十四、cc.spriteFrameCache 改造说明
    [SVN]创建本地的SVN仓库
    [C++]函数参数浅析
    [Windows Phone]AnimationHelper管理分散的Storyboard
    [Windows Phone]常用类库&API推荐
    [Windows Phone]模仿魔兽3技能按钮SkillButton
    [C++]引用浅析
    [C++]new和delete
    [C++]指针浅析
    [C++]C++中的运行时类型检测
  • 原文地址:https://www.cnblogs.com/GhostZCH/p/3961237.html
Copyright © 2011-2022 走看看