不透明指针_C语言

﹥>﹥吖頭↗ 提交于 2019-11-26 19:25:21
  1. C++与C的比较
    C++与C的最大区别是:C++是面向对象的编程语言,C是面向过程的编程语言。C++拥有封装、继承、多态等OO编程思想。C语言不具备这些内置功能。虽然C语言有结构体struct,可以将数据放在统一的结构中。但它不能控制外部用户对结构体内数据的访问权限。不像C++可以提供public、protected、private限定符来控制数据的访问权限。所以struct只是将数据打包,而class是将数据封装

  2. 不透明指针的作用
    不透明指针可以在C语言中实现数据的封装

  3. 什么是不透明指针
    C语言中,我们可以在未定义结构体时先声明此结构体的指针类型。形式如下:

    typedef struct Point* PointPtr;
    PointPtr pPoint = nullptr;
    

    此时PointPtr就是不透明指针类型。pPoint就是不透明指针。由于未定义结构体,所以pPoint引用不到Point结构体的具体数据。也就相当于class的private属性。从而实现了封装。

  4. 应用方式
    提供一个.h文件。文件中定义不透明指针类型。并extern几个全局函数提供真实数据的访问方法以及结构体开辟空间、释放空间的方法。.c文件中定义结构体并实现这些方法。代码如下:
    opacityPoint.h:

    #pragma once
    
    /************************************************
    //  不透明指针
    //  用C的方式实现封装即Private属性
    //
    ************************************************/
    
    typedef struct Point* PointPtr;
    
    extern PointPtr CreatePoint();
    extern void ReleasePoint(PointPtr* p);
    extern void SetX(PointPtr p, int x);
    extern int GetX(PointPtr p);
    extern int GetY(PointPtr p);
    
    
    

    opacityPoint.c:

    #include "opacityPoint.h"
    #include <memory.h>
    #include <assert.h>
    
    
    struct Point {
    	int x;
    	int y;
    };
    
    PointPtr CreatePoint()
    {
    	PointPtr p = (PointPtr)malloc(sizeof(struct Point));
    	assert(NULL != p);
    
    	return p;
    }
    
    void ReleasePoint(PointPtr* p)
    {
    	if (NULL != *p) {
    		free(*p);
    		*p = NULL;
    	}
    }
    
    void SetX(PointPtr p, int x)
    {
    	assert(NULL != p);
    
    	p->x = x;
    }
    
    int GetX(PointPtr p)
    {
    	assert(NULL != p);
    
    	return p->x;
    }
    
    int GetY(PointPtr p)
    {
    	assert(NULL != p);
    
    	return p->y;
    }
    

    main.c:

    #include <stdio.h>
    #include "opacityPoint.h"
    
    int main(void)
    {
    
    	PointPtr pPoint = CreatePoint();
    	
    	//pPoint->x;	//  error C2027: use of undefined type 'Point
    
    	SetX(pPoint, 6);
    	printf("x = %d, y = %d\n", GetX(pPoint), GetY(pPoint));	// x:6 y:随机数
    
    	ReleasePoint(&pPoint);
    
    	//printf("x = %d, y = %d\n", GetX(pPoint), GetY(pPoint));	// error pPoint is nullptr
    
    	getchar();
    	return 0;
    }
    

由于未提供y的设定函数SetY,所以main.c中无法对y的值进行设定。实现了权限控制。
5. 讨论
有人说不透明指针实现了ADT(abstract data type)抽象数据类型。本人并不赞同。因为定义结构体的过程就是对多个具体对象特征与本质的提取。也就是抽象。C语言本身就有抽象无需再利用不透明指针的技巧来实现抽象。另外,这也解释了面向对象的三大特征为何是封装、继承、多态。而不是抽象、继承、多态。因为面向过程也拥有抽象功能呐。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!