C++中直接存取类私有成员[360度]
?讀到《C++編程思想》48頁,“3.4?對象布局”一節時,看到這樣一段話:
?
?存取指定符是struct的一部分,他并不影響這個struct產生的對象,程序開始運行時,所有的存取指定信息都消失了。存取指定信息通常是在編譯期間消失的。在程序運行期間,對象變成了一個存儲區域,別無他物,因此,如果有人真的想破壞這些規則并且直接存取內存中的數據,就如在C中所做的那樣,那么C++并不能防止他做這種不明智的事,它只是提供給人們一個更容易、更方便的方法。
?既然是在編譯期間去掉了所有的存取限制屬性,那么能不能設計一段代碼繞過編譯器的檢查機制,又能在運行期間訪問類的私有成員呢??首先想到了條件轉移語句——編譯器對條件轉移代碼塊的編譯是否有可利用之處呢?雖然實驗失敗了,但我的第一想法確實是這個。示例代碼如下:
//tester.h
//Demo class
class tester
{
public:
?tester() : i(5), ch('x'){};
private:
?int i;
?char ch;
};
//test1.cpp
//Demo testing code
#include "tester.h"
#include<conio.h>
#include<iostream>
using namespace std;
void main(void)
{
?tester myTester;
?char* p = NULL;
?if (1 > 0)
?{
??p = &myTester.ch;??//Here is the point
?}
?cout << "Address of ch = " << (void*) p << endl; //The type modifier void* forces it to output the
????????????? //address, not its ?content
?cout << "ch = " << * (p) << endl;
?getch();??//Waits your action
?* p = 'y';
?cout << "Now ch = " << * (p) << endl;
}
?結果正如上面所說,失敗了:編譯器報錯:error C2248: 'ch' : cannot access private member declared in class 'tester'。不過這引發了更深一步的思考。C語言里面最活的就是指針了,平常最怕亂指的野指針,這一次就試試它!修改后的測試代碼如下:
//test2.cpp
//Demo testing code
#include "tester.h"
#include<conio.h>
#include<iostream>
using namespace std;
void main(void)
{
?tester myTester;
?char* p = NULL;
?p = (char*) &myTester + sizeof(int);??//Here is the point! Jumps sizeof(int) units of bytes!
?cout << "Address of ch = " << (void*) p << endl;?//The type modifier void* forces it to output the
??????????????//address, not the content.
?cout << "ch = " << * (p) << endl;
?getch();??//Waits your action
?* p = 'y';
?cout << "Now ch = " << * (p) << endl;
}
?查看輸出后可以發現,ch的內容已經修改了。不過通過指針強行訪問類的私有成員確實有點那個,嘿嘿。
總結
以上是生活随笔為你收集整理的C++中直接存取类私有成员[360度]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浙大python判断两个字符串是否为变位
- 下一篇: 返回值类型与函数类型不匹配_C++返回值