【轉】C++類中對同類對象private成員訪問


  私有成員變量的概念,在腦海中的現象是,以private關鍵字聲明,是類的實現部分,不對外公開,不能在對象外部訪問對象的私有成員變量.

  然而,在實現拷貝構造函數和賦值符函數時,在函數里利用對象直接訪問了私有成員變量,因而,產生了困惑.下面以具體實例進行說明:

  疑惑:為什么第26行和第32行代碼可以編譯通過,而第39行和第40行代碼會產生編譯錯誤?

class CTest {
public:
    CTest(int i); 
    CTest(const CTest& rhs);
    CTest& operator=(const CTest& rhs);
    void printCTest(const CTest& rhs);
private:
    int value;
};

CTest::CTest(int i):value(i)
{
    cout<<"Contructor of CTest"<<endl;
}

CTest::CTest(const CTest& rhs):value(rhs.value)
{
    cout<<"Copy contructor of CTest"<<endl;
}

CTest& CTest::operator=(const CTest& rhs)
{
    cout<<"Assign function of CTest"<<endl;
    if(this == &rhs)
        return *this;
    value = rhs.value;                //通過對象訪問私有成員變量
    return *this;
}

void CTest::printCTest(const CTest& rhs)
{
    cout<<rhs.value<<endl;        //通過對象訪問私有成員變量
}

int main()
{
    CTest t = 1;
    CTest tt = 2;
    //  cout<<t.value<<endl;        //通過對象訪問私有成員變量,編譯錯誤
    //  cout<<tt.value<<endl;        //通過對象訪問私有成員變量,編譯錯誤
    t.printCTest(tt);
}

  產生這種疑惑的原因是自己對私有成員變量的理解有誤,封裝是編譯期的概念,是針對類型而非對象的,在類的成員函數中可以訪問同類型實例對象的私有成員變量

  具體的解析如下:從變量value的符號是怎么解析的分析

1.確定符號的查找域

  如第26行代碼,當編譯器發現value變量時,它會在value變量所屬的對象rhs的類域中尋找該符號.

2.確定當前域中哪些符號可以訪問

  由第1步可知,當前查找的域是類域,而printCTest函數在CTest類體中,所以printCTest可以訪問CTest類中的所有變量(包括私有成員變量),因而value符號在CTest類域中被找到.

  如第39行代碼,main函數不在CTest類體中,所以main函數不可以訪問CTest類域中的私有成員變量.

3.符號已查找到,編譯通過

  類成員變量的訪問權限是編譯器強加的,編譯器可以找到value,通過編譯,自然就可以訪問到value變量的值.

直覺上,我們會以為第26行代碼中value符號的查找域應該是對象rhs對應的作用域,然而C++編譯器的實現卻是在對象rhs的類域查找value符號.

  啟發:有些直覺是靠不住的,需要深入分析其背后的實現原理,才可以理解透徹.

 

  總結:C++的訪問修飾符的作用是以類為單位,而不是以對象為單位。
  通俗的講,同類的對象間可以“互相訪問”對方的數據成員,只不過訪問途徑不是直接訪問.
  步驟是:通過一個對象調用其public成員函數,此成員函數可以訪問到自己的或者同類其他對象的public/private/protected數據成員和成員函數(類的所有對象共用),而且還需要指明是哪個對象的數據成員(調用函數的對象自己的成員不用指明,因為有this指針;其他對象的數據成員可以通過引用或指針間接指明)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM