我們知道,c++類私有方法和變數是不允許通過類例項直接訪問的,這樣子的操作會導致編譯報錯。但有沒有方法訪問到呢?有的。
首先,我們需要知道c++和c語言本質上是沒有什麼區別的,c++只是語法層面上對c語言的封裝。所有c函式,只要有宣告和定義,那就可以使用,不存在public和private的區分。c++的public, private和protected限定的作用只在於編譯期,當我們進入到執行期的時候,就無所謂public/private/protected了。
然後我們知道,函式都是儲存在**段的,那麼c++類的成員函式必然也儲存在**段。但是c++類成員函式和普通的函式有什麼區別呢?例子如下:
class cls
}
上面的cls類又乙個成員函式void func()。而func只能夠通過cls().func()的方式呼叫,不能直接func()呼叫。
看起來c和c++的函式有很大的區別?
其實不然,我們知道,c++的成員函式裡面可以使用this指標。但是我們上面cls().func()並沒有往func函式中傳遞this指標,func函式怎麼獲取的this指標呢?
cls().func()左邊有個cls例項,也即是說,func()中的this指標就是左邊的cls例項。我們將func函式轉換一下:void func(cls* this)。這種寫法就很合乎c語言的寫法了。所以我們認為cls().func()等價於
auto cls = cls();
func(&cls);
接下來,整個類轉換一下:
struct cls {};
void func(cls* this) {}
cool!
那麼c++語言中類成員變數在記憶體中怎麼儲存的呢?如下:
class cls
struct cls
在c語言裡面,結構體cls可以在棧中建立,也可以在堆中建立,anyway,成員a和成員b的位址始終是緊挨著的,而成員a的位址就是整個結構體的起始位址。
好,不多說,進入主題,如何在外部訪問c++類的私有方法和私有變數(僅供娛樂,平時寫**勿以為參考)
定義類如下:
class cls
inline int geta()
inline int getb()
private:
void pri_func()
int a = 0;
int b = 0;
};
類cls提供三個公開方法:pub_func, geta, getb
現在我想要呼叫私有方法pri_func, 並且還要修改私有成員a和b的值
呼叫私有方法pri_func
第一步:呼叫pub_func,並編譯生成a.out
int main()
第二步:獲取pri_func函式的真實函式名
nm -a a.out | grep pri_func
得到編譯器改名後的pri_func為_zn3cls8pri_funcev
第三步:宣告並呼叫_zn3cls8pri_funcev
extern "c"
int main()
執行上述**,可以發現,pri_func中的列印輸出了
第四步:觀察a的值是否被修改
int main()
毫無疑問,此時列印出a的值為15
接下我們修改b的值。回溯上面講的,a的位址就是cls例項的起始位址,a,b是連續的,所以,其實b的位址就是 &cls + 4bytes。寫成**如下:
int main()
列印結果就是13
需要注意的就是,如果類中存在虛函式,那麼cls的首位址就不是a的位址了,而是記錄虛函式表的位址,a,b的位址將順移乙個指標的大小。
這些操作大家平時玩玩就好了,千萬不要寫到工程**裡面去
Python訪問類的私有屬性和私有方法的正確姿勢
encoding utf 8 classperson 只允許擁有私有的name和age屬性 slots name age def init self name,age self.name name self.age age property defname self returnself.name ...
類的私有屬性和私有方法
class role def init self,name,role,weapon,value 100,money 1500 建構函式 self.name name 例項變數 靜態屬性 作用域就是實力本身 self.role role self.weapon weapon self.value va...
外部方法呼叫內部 私有屬性和私有方法
應用場景 定義方式 不要問女生的年齡 self.age 18 def secret self print 我的年齡是 d self.age xiaofang women 小芳 私有屬性,外部不能直接訪問 print xiaofang.age 私有方法,外部不能直接呼叫 xiaofang.secret...