-
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語言本身就有抽象無需再利用不透明指針的技巧來實現抽象。另外,這也解釋了面向對象的三大特徵爲何是封裝、繼承、多態。而不是抽象、繼承、多態。因爲面向過程也擁有抽象功能吶。