![](/img/trans.png)
[英]why c++ allows pointers if they can generate problems like accessing private members?
[英]Why this code allows accessing private variables
幾天前,我遇到了這種方法(作為C ++課程中編程任務的解決方案之一)。
#include <iostream>
struct C {
C(int i) { m_i = i; }
private:
int m_i;
};
template<typename Tag, int C::* M>
struct Rob {
friend
int C::* get(Tag) {
return M;
}
};
template<typename D>
struct AcessorTag {
typedef D C::*type;
};
template struct Rob<AcessorTag<int>, &C::m_i>;
int &get_c(C &cls) {
return cls.*get(AcessorTag<int>());
}
int main()
{
C c(13);
std::cout << get_c(c);
return 0;
}
您能否解釋一下為什么編譯此代碼? 這里發生的幾乎所有事情是:1)我們將指針指向成員作為結構模板的參數傳遞給我們; 2)聲明一個朋友函數,該函數僅將該指針返回給成員。
這是標准的C ++嗎? (我已經在VS 2015上進行了測試)
get
函數是struct Rob<>
的朋友,但不是struct C
。 無論如何, struct C
似乎沒有朋友,那么為什么它的私有成員可以訪問?
謝謝!
除了缺少get
函數的前向聲明外,此代碼還可以正常工作並且符合標准。 由於適用於模板的顯式實例化定義的特殊規則,因此可以使用此代碼:
17.8.2顯式實例化[temp.explicit]
14通常的訪問檢查規則不適用於用於指定顯式實例化的名稱。 [注:特別是,函數聲明符中使用的模板參數和名稱(包括參數類型,返回類型和異常規范)可能是私有類型或對象,通常是無法訪問的,並且模板可能是成員模板或成員函數通常是無法訪問的。 —尾注]
所以寫
template struct Rob<AcessorTag<int>, &C::m_i>;
將繞過常規的訪問檢查,並提供指向否則無法訪問的成員的指針,以get
函數體。
當然,您的代碼無法使用gnu c ++和clang ++進行編譯; 標識符get
不是C
的成員。 即使您嘗試實例化Rob
,例如
Rob<AcessorTag<int>, &C::m_i> rob;
您獲得
error: 'int C::m_i' is private.
您可以隨時詢問Microsoft他們的c ++編譯器是否符合任何標准。 如果他們完全回答,請告訴我他們的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.