最近在寫簡單的寫點練手的代碼,其中有一個就是自己寫一個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,這個變量是不能被修改了,但是如果你把這個變量的地址取出來再重新操作,仍然是可以的。所以我一直以爲這種很多規則和邏輯是在內存裏面實現的,其實不是的。本質上都是在編譯器上產生的,這個想明白了也就沒有那麼玄乎了。
好了,今天就到這裏吧。