1. 程式人生 > >C++中類的訪問許可權針對的是類而不是物件!(為什麼類中的函式可以訪問物件的私有成員?)

C++中類的訪問許可權針對的是類而不是物件!(為什麼類中的函式可以訪問物件的私有成員?)

我們首先看一段程式:

class A {
private:
    int i;
public:
    A(int i): i(i) {}
    void print(A a) {
        cout << a.i <<endl;
    }
};

int main() {
    A B(5);
    A C(4);
    B.print(C);
    return 0;
}

編譯通過,程式執行結果為:

4

Process returned 0 (0x0)   execution time : 0.048 s
Press any key to continue.

這個程式非常的簡單,但我們仔細一瞅會發現一個有趣的問題:private的變數i怎麼直接可以通過物件訪問了!
我們知道在C++的類中訪問許可權分為private,protected,public三種:

  • private; that is, its name can be used only by members and friends of the class in which it is declared.
  • protected; that is, its name can be used only by members and friends of the class in which it is declared, and by members and friends of classes derived from this class (see 11.5).
  • public; that is, its name can be used anywhere without access restriction.

上面寫的清清楚楚,private變數只可以被類的成員和桉樹或者類的友元類/友元函式訪問。但上面的程式為什麼又執行通過了呢?

我們繼續看下面的一個程式:

class A {
private:
    int i;
public:
    A(int i): i(i) {}
    void print(A a) {
        cout << a.i <<endl;
    }
};

void test(A a) {
    cout << a.i <<endl;
}

int
main() { A B(5); test(B) return 0; }

程式編譯出錯,錯誤資訊:F:\ACM\simple_test\Cpp_test\main.cpp|57|error: ‘int A::i’ is private|

這次是符合我們預期的!那為什麼這兩次結果不一樣呢?

我們仔細看上面的定義會發現,訪問許可權控制其實是針對而言的,並不是物件
也就是說編譯器遇到i變數時,它會在i變數所屬的class A尋找該符號,很顯然在這個類中是可以直接訪問i變數的。所有在print函式中可以訪問i變數,甚至可以方位其他類物件的i的變數。
而在test()函式中,因為它的作用域已經超過了class A,所有就沒有辦法訪問i了。

總結

C++的訪問修飾符的作用是以類為單位,而不是以物件為單位。
俗的講,同類的物件間可以“互相訪問”對方的資料成員,只不過訪問途徑不是直接訪問。
方法是:通過一個物件呼叫其public成員函式,此成員函式可以訪問到自己的或者同類其他物件的public/private/protected資料成員和成員函式(類的所有物件共用),而且還需要指明是哪個物件的資料成員(呼叫函式的物件自己的成員不用指明,因為有this指標;其他物件的資料成員可以通過引用或指標間接指明)