1. 程式人生 > >【C++】 私有成員變數的理解

【C++】 私有成員變數的理解

轉載地址:https://www.cnblogs.com/oraser/p/5888116.html

【C++】 私有成員變數的理解

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

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

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

複製程式碼

複製程式碼

 1 class CTest {
 2 public:
 3     CTest(int i); 
 4     CTest(const CTest& rhs);
 5     CTest& operator=(const CTest& rhs);
 6     void printCTest(const CTest& rhs);
 7 private:
 8     int value;
 9 };
10 
11 CTest::CTest(int i):value(i)
12 {
13     cout<<"Contructor of CTest"<<endl;
14 }
15 
16 CTest::CTest(const CTest& rhs):value(rhs.value)
17 {
18     cout<<"Copy contructor of CTest"<<endl;
19 }
20 
21 CTest& CTest::operator=(const CTest& rhs)
22 {
23     cout<<"Assign function of CTest"<<endl;
24     if(this == &rhs)
25         return *this;
26     value = rhs.value;                //通過物件訪問私有成員變數
27     return *this;
28 }
29 
30 void CTest::printCTest(const CTest& rhs)
31 {
32     cout<<rhs.value<<endl;        //通過物件訪問私有成員變數
33 }
34 
35 int main()
36 {
37     CTest t = 1;
38     CTest tt = 2;
39     //  cout<<t.value<<endl;        //通過物件訪問私有成員變數,編譯錯誤
40     //  cout<<tt.value<<endl;        //通過物件訪問私有成員變數,編譯錯誤
41     t.printCTest(tt);
42 }  

複製程式碼

複製程式碼

 

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

具體的解析如下:從變數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符號.

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