關於C++實現類外不能訪問私有數據的理解

        最近在寫簡單的寫點練手的代碼,其中有一個就是自己寫一個String類,能夠實現構造函數、賦值構造函數、符號函數重載以及析構函數。順便提一句,這個問題如果作爲面試應屆生的話,還是很不錯的一個問題。代碼如下:

class ZString
{
private: 
	char* pc_buf;

public:
	ZString(const char *pcbuf);
	ZString(const ZString &sZstring);
	~ZString();
	ZString operator=(const ZString sZstring);
	void OutPut();
};

ZString::ZString(const char *pcbuf)
{
	if(NULL != pcbuf)
	{
		pc_buf = (char *)malloc(strlen(pcbuf) + 1);
		memcpy(pc_buf, pcbuf, strlen(pc_buf) +1);
	}
}

ZString::ZString(const ZString &sZstringVal)
{
	if (NULL != sZstringVal.pc_buf)
	{
		pc_buf = (char *)malloc(strlen(sZstringVal.pc_buf) + 1);
		memcpy(pc_buf, sZstringVal.pc_buf, strlen(sZstringVal.pc_buf) + 1);
	}
}
ZString::~ZString()
{
	if (NULL != pc_buf)
	{
		free(pc_buf);
		pc_buf = NULL;
	}
}
ZString ZString::operator=(const ZString sZstring)
{
	ZString zTem(sZstring.pc_buf);
	return zTem;
}
void ZString::OutPut()
{
	cout << pc_buf << endl;
}

其實整個代碼非常簡單,但是有一點比較有意思,就是在重載函數裏面,有這樣一句代碼:

ZString ZString::operator=(const ZString sZstring)
{
	ZString zTem(sZstring.pc_buf);
	return zTem;
}

可以看到,我實現了對象.私有數據的直接調用。如果這要是在main函數裏面是絕對不會被允許的,但是在類內就可以調用。網上查了一下,很多人都說私有數據是在類內可以訪問的,類外無法訪問,哪怕是類內可以訪問其對象的私有數據也可以。然後我的問題又來了,這個功能是怎麼實現的呢?怎麼做到類外是無法訪問的呢?答案也比較簡單:編譯器。其實就是在編譯器進行處理的時候不讓你在類外調用能編譯通過。原因有兩個:1、如果你訪問了,去編譯代碼的時候直接編譯報錯,而不是鏈接或者運行的時候出現問題。2、其實你可以繞過編譯器,代碼功能仍然是可以訪問呢,比如如下:

class ZClass
{
private:
	char szArray[10];


public:
	void GetMemberAddrByPoint(char *&c);
	char* GetMemberAddrByFunc();
	void InitClass();
};

//直接把私有數據的地址賦值給一個變量
void ZClass::GetMemberAddrByPoint(char *&c)
{
	c = szArray;
}

//直接返回地址
char* ZClass::GetMemberAddrByFunc()
{
	return szArray;
}

void ZClass::InitClass()
{
	for(int i = 0; i < 10; i++)
	{
		szArray[i] = 'a'+ i;
	}
}

int main()
{
	
	ZClass cTestClass;
	cTestClass.InitClass();
	char *point = cTestClass.GetMemberAddrByFunc();
	cout << point[1] << endl;
	char *point2;
	cTestClass.GetMemberAddrByPoint(point2);
	cout<< point2[2] <<endl;
}

可以看到上面的代碼,其實只要是把私有數據的地址給拿出來,你是可以訪問的,也是可以操作的。這個就說明私有數據的內存其實沒有什麼特殊的地方,只是編譯器限制罷了。這個的原理應該是和const裏面是一樣的。你把一個變量加上了const,這個變量是不能被修改了,但是如果你把這個變量的地址取出來再重新操作,仍然是可以的。所以我一直以爲這種很多規則和邏輯是在內存裏面實現的,其實不是的。本質上都是在編譯器上產生的,這個想明白了也就沒有那麼玄乎了。

好了,今天就到這裏吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章