C 突破private訪問許可權的黑科技

2021-07-16 13:46:09 字數 1537 閱讀 7276

昨天,有位同事丟擲了乙個問題:

乙個class內有乙個private屬性的struct型別,然後他想做的事情是,在繼承該class的子類中復用這個型別,但是由於該類似的private屬性,編譯是不通過的。

因此就引入了乙個問題:如何突破class的private屬性限制——試圖破壞class的封裝性,有點「逆天而行」的感覺。

查了一下,方法確實是有的。

假設有以下類:

m_nprivate

class x

​ templatevoid func(const t &t)

{}​ const

int getvalue()

};

void *p = &x;        // 獲取類的起始位址,其實也就是m_nprivate資料成員的位址

int *n = (int *)p;

​int tmp = 2;

*n = tmp; // 改寫其值

​cout

<< x.getvalue() << endl; // 輸出為2

這種方法的缺點:計算偏移量是個麻煩的事情,涉及到記憶體對齊、編譯器版本等,可移植性低,而且這種方法只能訪問成員變數,卻不能達到「使用private內建型別」的目的。

在類x的定義前,加一句:

#define

private

public

該方法可以欺騙編譯器,讓它把「private」當作「public」。

然而它有兩個違背標準的行為:

1)#define 保留字是非法的

2)違反了唯一定義規則(odr,one definition rule),然而類的底層記憶體布局沒改變,故可行

m_nnotprivate

// 同x的記憶體布局,將變數or型別定義改為public

class y ;​

void func(x* xptr)

首先我們將x型別的指標轉換為y型別的指標,在編譯器看來,我們訪問的是y型別的public成員m_nnotprivate,因此編譯通過,然而事實上該指標是x型別的,由於y跟x的記憶體布局是完全一樣,因此訪問y的m_nnotprivate成員實際上也就是在訪問x的m_nprivate成員。

類似的方法就是,在y中增加乙個非虛成員函式,該函式用來返回m_nprivate的位址。

類似以上方法,不過是通過新增友元宣告來訪問的~

如果x中存在乙個成員模版,那麼可以這樣子:

namespace;}

​template

<>

void x::func(const y&) //特化

​void test()

這種方法利用了x具有乙個成員模板的事實,通過特化函式模版,來打入敵人內部。**完全符合標準,標準也確保這種行為會按照編碼者的意圖行事。boost和loki中大量運用此手法。

以上方法參考:

C 突破private訪問許可權的黑科技

如何突破class的private屬性限制 試圖破壞class的封裝性,有點 逆天而行 的感覺。includeusing namespace std class x templatevoid func const t t const int getvalue friend void func x x...

突破訪問許可權

我們在寫 的時候,按約定都是把成員資料放到private訪問區中,然後在通過相應的函式來訪問。那又有什麼樣的 可以突破訪問許可權來直接操作類中private區段中的成員資料呢?首先,我們想到了指標,對吧 指標可是萬能之王,然而也是萬惡之源。那我們就先來看看指標如何突破馬其諾防線的。先定義乙個測試類 ...

建構函式 訪問許可權private

一 建構函式 具有建構函式的類會在每次建立新物件時先呼叫此方法,所以非常適合在使用物件之前做一些初始化工作。如果子類中定義了建構函式則不會隱式呼叫其父類的建構函式。要執行父類的建構函式,需要在子類的建構函式中呼叫parent construct 如果子類沒有定義建構函式則會如同乙個普通的類方法一樣從...