• C语言中不透明指针和对象


    C语言中的不透明指针和对象

    在C语言中,如果我们想实现类似于面向对象的方法,把接口API暴露给使用者,而内部数据隐藏起来私有。该怎么办呐?本文介绍一种实用的设计模式,使用不透明指针(句柄)实现类似于面向对象的操作。

    不透明指针是一种很好的设计模式。

    在C语言中构造一个对象:

    • 定义一个结构包含我们需要的数据
    • 定义一些方法(函数)来处理一些事情,这些函数的第一个参数是结构的指针
    • 申明一个变量作为对象的实例

    这种不透明数据结构的实现方式多在底层操作系统中用到,最近看freeRTOS代码,其中的核心数据结构任务控制块就是在task.c文件中实现,在task.h中则是使用这样一个不透明结构体TaskHandle_t,其内部结构struct tskTaskControlBlocktask.c中实现。

    //task.h中不透明结构体(句柄)定义如下
    struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */
    typedef struct tskTaskControlBlock * TaskHandle_t;
    
    //task.s中定义结构体的具体内容
    typedef struct tskTaskControlBlock       /* The old naming convention is used to prevent breaking kernel aware debuggers. */
    {
        volatile StackType_t * pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
    
        #if ( portUSING_MPU_WRAPPERS == 1 )
            xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer.  THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
        #endif
    
    ...
    
        #if ( configUSE_POSIX_ERRNO == 1 )
            int iTaskErrno;
        #endif
    } tskTCB;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    下面举一个例子,介绍不透明指针的用法。例子中定义一个结构体,里面包含两个数据成员,要构建这样一个对象,对外提供一个算法。例子中这个算法很简单,就是两个数据加起来,返回计算结果。

    例子中三个文件:

        main.c
        test.c
        test.h
    
    • 1
    • 2
    • 3

    test.c文件

    #include  "test.h"
    #include  "stdlib.h"
    
    typedef struct myDataType
    {
        int a;
        int b;
    }ST_MyData_T;
    
    myDataHandle CreatMyData(int a, int b)
    {
        myDataHandle pstmyData = malloc(sizeof(myDataHandle));
        pstmyData->a = a;
        pstmyData->b = b;
        return pstmyData;
    }
    
    int  GetMyResult(myDataHandle pstVal)
    {
        return (pstVal->a)*(pstVal->b);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    test.h文件

    #ifndef  _TEST_H_
    #define  _TEST_H_
    
    struct myDataType;
    typedef  struct myDataType* myDataHandle;
    
    extern  myDataHandle CreatMyData(int a, int b);
    extern  int  GetMyResult(myDataHandle pstVal);
    #endif  //_TEST_H_
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    main.c文件

    #include 
    #include "test.h"
    
    void main(){
        myDataHandle  pmydata;
        pmydata = CreatMyData(2,3);
        printf("result = %d\n",GetMyResult(pmydata));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    main.c中使用不透明结构体类型定义一个对象(句柄),使用接口函数接口来操作对象,因为对象的类型没有直接在.h文件中定义,无法直接访问指针中的成员,起到了隐藏对象成员的作用。

    参考:
    Practical Design Patterns: Opaque Pointers and Objects in C: https://interrupt.memfault.com/blog/opaque-pointers

  • 相关阅读:
    Mac配置host
    通过代码加解析的方式带领大家分析 :数组与指针的关系
    LeetCode回溯算法组合问题——216.组合总和III
    【强化学习论文合集 | 2021年合集】七. ICRA-2021 强化学习论文
    【Android#8】Editext和软键盘的爱恨情仇:自定义底部输入框被部分遮挡+IM聊天界面输入框表情面板的跳变问题+
    ISE_ChipScope Pro的使用
    Centos7如何扩容未做lvm的GPT硬盘
    zookeeper第二章:API接口
    python 实现euler modified变形欧拉法算法
    【Python】读取显示pgm图像文件
  • 原文地址:https://blog.csdn.net/aoyousihaiqiuqihuang/article/details/128059208