不透明指針_C語言

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章