PIMPL 隱藏介面的實現細節

2021-10-24 16:05:22 字數 1678 閱讀 8081

有時候我們需要提供對外的api,通常會以標頭檔案的形式提供。舉個簡單的例子:

提供乙個從某個指定數開始列印的介面,標頭檔案內容如下:

#ifndef _test_api_h

#define _test_api_h

//test_api.h

class testapi

void testprint(int num);

private:

int start_ = 0;

};#endif //_test_api_h

實現檔案如下:

#include "test_api.h"

#include //test_api.cc

testapi::testprint(int num);

test_api.testprint(15);

return 0;

}從前面的內容來看, 一切都還正常,但是有什麼問題呢?

第一點可以很明顯的看出來,其中的私有變數star_能否在標頭檔案中看到,如果實現越來越複雜,這裡可能也會出現更多的私有變數。有人可能會問,私有變數外部也不能訪問,暴露又何妨?

不過你只是提供幾個介面,給別人看到這麼多資訊幹啥呢?這樣就會導致實現和介面耦合在了一起。

另外一方面,如果有另外乙個庫使用了這個庫,而你的這個庫實現變了,標頭檔案就會變,而標頭檔案一旦變動,就需要所有使用了這個庫的程式都要重新編譯!

這個代價是巨大的。

所以,我們應該盡可能地保證標頭檔案不變動,或者說,盡可能隱藏實現,隱藏私有變數。

pointer to implementation,由指標指向實現,而不過多暴露細節。廢話不多說,上**:

#ifndef _test_api_h

#define _test_api_h

#include //test_api.h

class testapi;

#endif //_test_api_h

從這個標頭檔案中,我們可以看到:

我們再來看下具體的實現:

#include "test_api.h"

#include //test_api.cc

class testapi::testimpl

testimpl() = default;

~testimpl() = default;

private:

int start_;

};void testapi::testimpl::testprint(int num)

//注意,析構函式需要

testapi::~testapi() = default;

從實現中看到,testapi中的testprint呼叫了testimpl中的testprint實現,而所有的具體實現細節和私有變數都在testimpl中,即便實現變更了,其他庫不需要重新編譯,而僅僅是在生成可執行檔案時重新鏈結。

從例子中,我們可以看到pimpl模式中有以下優點:

當然了,由於實現在另外乙個類中,所以會多一次呼叫,會有效能的損耗,但是這點幾乎可以忽略。

為何優先選用unique_ptr而不是裸指標?

認真理一理c++的建構函式

這才是現代c++單例模式簡單又安全的實現

隱藏struct具體實現細節

我們知道對於struct,其所有的成員預設情況下是所有對外可見的,即為public屬性。但是有時候為了提高程式的封裝性,我們需要將struct的內容細節隱藏起來,怎麼做呢?可以使用下面這種做法達到目的。a.h typedef struct a at class test a.cpp include ...

介面的實現

1 介面的實現 class 類名 implements 介面1,介面2,介面3 方法1 方法2 介面實現的注意事項 1 為介面中所有的方法提供具體的實現。2 必須遵守重寫的所有規則。重寫的規則 1 子類的重寫方法不能丟擲更大的異常 2 子類的重寫方法不能有更小的訪問範圍 父類 public void...

C 介面 介面的實現

c 定義了介面後,就要在子類中實現。c 中通常把子類和父類的關係稱為繼承,子類和介面的關係稱為實現。子類可以繼承乙個父類,可以實現多個介面。介面中不能定義建構函式,所以介面不能例項化。下面我們看例子 using system public inte ce ichoose public class t...