#undef private
很明顯出現這類需求就說明設計已經很有問題了,建議還是重新審視一下各個類的關係。
要不要用和能不能是兩回事class A
{
public:
int x;
private:
int y;
};
int main(int argc, char* argv[])
{
A a;
//a.x = 1;
//a.y = 1; error
int* p = (int*)a;
*p = 1; //a.x = 1
*(p + 1) = 1; //a.y = 1
return 0;
}
私有變數也只是在編譯時不能被非友元類訪問
用地址訪問就好了
不過比較麻煩,也容易出問題在有虛函數的時候還需要考慮虛表的大小所以還是用友元類吧
按照偏移量計算並不是個好辦法,假如類的成員有不同的數據類型,那麼必然會有問題
所以稍微比較正常的方法是重新定義一個類,所有成員都和前一個一樣,不過訪問許可權都是public
再把指針reinterpret_cast一下就好
這種方法只要這兩個類在相同的模塊,使用相同的編譯器、相同的編譯選項進行編譯,一般是不會有問題的
class A
{
public:
A():m_x(0), m_y(2.0){}
private:
int m_x;
double m_y;
};
class PA
{
public:
A():m_x(0), m_y(2.0){}
int m_x;
double m_y;
};
然後
A *p1 = new A;
PA * p2 = reinterpret_cast&(p1);
p2-&>m_y;
但是這個方法依然很二逼,因為這個問題本來就很扯淡
屋子有門,我可以教你怎麼砸牆,但是牆塌了你被埋了不是我的事
計算好偏移量直接取,出了問題別找我。class A{
private:
int m_xxx;
int m_yyy;
};
class B{
public:
void doSomething(A a){
(*((int*)(a))) = 123; // a.m_xxx = 123;
(*((int*)(a) + 1)) = 312; // a.m_yyy = 312;
}
};
因為很重要所以再強調一下,這樣做挺麻煩的,如果出了問題(比如被其他閱讀到這段代碼的人揍了、出現了莫名其妙的bug、偏移量算錯了、目標平台很獵奇……)別找我。
對了,這裡還有一種-不那麼容易被噴-腦洞大開的寫法,他可以讓你被噴的幾率減少0.000001%(我猜的):class A{
private:
int m_xxx;
int m_yyy;
};
struct C{
int m_xxx;
int m_yyy;
};
class B{
public:
void doSomething(A a){
reinterpret_cast&(a)-&>m_xxx = 1;
reinterpret_cast&(a)-&>m_yyy = 2;
}
};
如果有虛函數,地址偏移貌似就不靈了吧,對不同的編譯器虛函數表指針的存放順序應該是不同的。
public: setxxx(); //class yyy only
寫個帶審查的set,get。傳入一個介面作為憑證。
類A寫一個公有函數把私有成員提供或賦值,然後調用類A函數
nested class
紙上談兵的方法是,讓類的一個公共成員函數返回這個類的一個私有數據成員的引用(引自Visual C++ 2008大學教程 第二版 P418
)。
既然是私有變數,就是不想讓其它類訪問,這是C++中對類的私有變數的定義。
你現在已經有需求訪問A的私有變數了,正確方法是:
- 把類A中的變數聲明為Public。
- 添加公有方法。
其它的方法都會對程序的可理解性、可維護性造成各種困擾,非正途。
linux kernel source 裡面有一個macro叫container_of,你可以參考一下裡面如何普遍地計算偏移量
所謂公有成員還是私有成員,這種訪問控制完全是編譯期的概念好不好!運行態時不受任何控制,只要你知道它在哪兒(也就是地址)
調用類a的公共方法,以類組合的形式編碼?新手求輕拍
推薦閱讀: