1. 程式人生 > >對C++中訪問private變數的思考

對C++中訪問private變數的思考

問題:如果自己動手寫CString類的建構函式,拷貝建構函式,解構函式,賦值運算子等,那麼該如何寫?
參考程式碼如下

#include <memory>
class MyString {
private:
    char *m_data;
public:
    MyString();
    MyString(const char* ptr);
    MyString(const MyString& rhs);
    ~MyString();
    MyString& operator=(const MyString& rhs);
};
//預設的建構函式
MyString::MyString():m_data(new char[1]) { m_data[0]='\0'; } //使用const char* 來初始化 MyString::MyString(const char* ptr) { if (NULL == ptr) { m_data = new char[1]; *m_data = '\0'; } else { int len = strlen(ptr); m_data = new char[len + 1]; strcpy(m_data, ptr); } } //拷貝建構函式
MyString::MyString(const MyString& rhs) { int len = strlen(rhs.m_data);//注意,訪問了私有成員變數 m_data = new char[len + 1]; strcpy(m_data, rhs.m_data);//依舊訪問了私有成員變數 } //賦值操作符 MyString& MyString::operator =(const MyString& rhs) { if (this != &rhs) { delete[] m_data; m_data = new
char[strlen(rhs.m_data)+1];//依舊訪問了私有成員變數 strcpy(m_data, rhs.m_data);//依舊訪問了私有成員變數 } return *this; }

編譯程式,未出現錯誤。但是從上述的程式碼中可以看出,我們訪問了rhs的私有成員變數m_data。從private的定義來看,我們是不能通過rhs訪問私有變數的,但是上述程式碼並未出現錯誤,這是為什麼?
對於類中的成員函式呼叫問題,我們知道,在編譯器將引數壓棧之前,會首先將this指標壓棧,且訪問成員變數也是通過this指標來訪問的,也就是說如下程式碼

void MyString::copy(const MyString &rhs)
{
    m_data= rhs.m_data;
}

相當於

void MyString::copy(MyString *this ,const MyString &rhs)
{
    this->m_data= rhs.m_data;
}

即this指標可以訪問私有成員m_data,那麼相應的rhs也可以訪問其私有成員m_data:編譯器按照相同的方式處理對私有成員的訪問。

在《C++PL》10.2.2 訪問控制 這一節寫到
1. “私有部分(private)只能由成員函式使用; 公用部分(public)則構成了該類的物件的公用介面.”
2. “對私有成員的保護依靠的是對於使用類成員名稱的限制. 可以通過地址操作和顯示的型別轉換等繞過這些限制. C++ 的保護只是為了避免無意的失誤, 而不是為了防止精心策劃的計謀(騙局).”

周星星(http://blog.vckbase.com/bruceteen)中:訪問許可權是應該對class控制還是應該對object控制,在各個語言裡不盡相同,但C++選擇了class。可能周星星的話更好的詮釋了為什麼可以訪問rhs的私有成員m_data.