-
C++与C的比较
C++与C的最大区别是:C++是面向对象的编程语言,C是面向过程的编程语言。C++拥有封装、继承、多态等OO编程思想。C语言不具备这些内置功能。虽然C语言有结构体struct,可以将数据放在统一的结构中。但它不能控制外部用户对结构体内数据的访问权限。不像C++可以提供public、protected、private限定符来控制数据的访问权限。所以struct只是将数据打包,而class是将数据封装。 -
不透明指针的作用
不透明指针可以在C语言中实现数据的封装。 -
什么是不透明指针
C语言中,我们可以在未定义结构体时先声明此结构体的指针类型。形式如下:typedef struct Point* PointPtr; PointPtr pPoint = nullptr;
此时PointPtr就是不透明指针类型。pPoint就是不透明指针。由于未定义结构体,所以pPoint引用不到Point结构体的具体数据。也就相当于class的private属性。从而实现了封装。
-
应用方式
提供一个.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语言本身就有抽象无需再利用不透明指针的技巧来实现抽象。另外,这也解释了面向对象的三大特征为何是封装、继承、多态。而不是抽象、继承、多态。因为面向过程也拥有抽象功能呐。
来源:https://blog.csdn.net/qq_20938855/article/details/99052497