2012-01-01 89 views
7

我想我知道平易的,但我不知道如果我理解的知名度很清楚班級成員的可見度?

例如:

class X 
{ 
    int x; 
}; 

在這裏,「X」是隻在課堂上,但訪問外部可見的類。如果我是正確的,有人可以解釋回答關於如何控制能見度的文本。

(C++ 03/11.0)應該注意的是,它是對成員和基類的訪問,它控制着 而不是它們的可見性。成員的名字仍然是 可見,並且當基類不可訪問時,隱式轉換爲基類仍然是 。建立給定結構的解釋不考慮訪問控制。如果所建立的解釋使用 不可訪問的成員名稱或基類,則該結構爲 不合格。

+0

您應該要求澄清該答案的評論。 – 2012-01-02 00:27:35

+1

@ TomalakGeret'kal:我會從我的問題中刪除對該答案的引用。 – user1086635 2012-01-02 00:37:06

+1

恩......這與我所說的正好相反。 – 2012-01-02 00:56:26

回答

7

也許這個例子可以幫助:

class Bob 
{ 
private: 
    int foo(int, int); 
}; 

class David : Bob 
{ 
    void goo() { 
     int a = foo(1, 2); // #1 
    } 
}; 

class Dani : Bob 
{ 
    void foo(); 
    void goo() { 
     int a = foo(1, 2); // #2 
    } 
}; 

線#1,名稱foo可見,但其名稱的功能是不是(在賬戶被私下Bob訪問)。這是一個編譯錯誤,但編譯器知道有一個可能的函數Bob::foo匹配,但不可訪問。

線#2,名稱foo僅指Dani::foo,而Bob::foo不可見(因爲它是隱藏),所以根本就呼叫foo(1, 2)沒有匹配的功能。這也是一個編譯錯誤,但是這次錯誤是根本沒有匹配的函數。

+1

我可以知道它會造成什麼困惑嗎? – user1086635 2012-01-02 00:45:19

+0

@ user1086635不確定你的意思在這裏:行號只是不符合描述。 1號線是「鮑勃類」,但他似乎是「int foo(int,int);」而第2行是「{。」措辭需要編輯。 – Serodis 2012-01-02 01:15:45

+0

@Serodis:引用是用註釋'//#1'等標記的行。這種註釋風格在SO上是常見的做法,因爲源塊沒有任何其他形式的易於看到的編號。 – 2012-01-02 01:19:38

7

C++有一些關於私有類成員名稱可見性和可訪問性的深奧特徵。根據定義,私人類成員名稱只能由班級成員和朋友訪問。然而,可見性的規則可能會混淆許多。他們可以總結如下。

  1. 私人會員的名字只能被其他會員和朋友使用。
  2. 私有成員對於所有可以看到類定義的代碼都是可見的。這意味着即使在這個翻譯單元中永遠不需要它的參數類型也必須聲明它...
  3. 重載解析發生在可訪問性檢查之前。

在C++今日( 「C++ 03」 和更早的變種),可達性和可見性的概念是 獨立。只要「 作用域」中的類和名稱空間成員都可見,並且沒有機制從聲明的角度減少這種可見性。 輔助功能只是類成員的參數,與 可見性的概念正交。對於新手C++程序員來說,後一種觀察常常令人驚訝。看到這個PDF

考慮下面的例子。

#include < complex> 

class Calc 
{ 
    public: 
     double Twice(double d); 
    private: 
     int Twice(int i); 
     std::complex Twice(std::complex c); 
}; 

int main() 
{ 
    Calc c; 
    return c.Twice(21); // error, Twice is inaccessible 
}  

當編譯器將呼叫解析爲一個功能,它做了三分主要的事情,依次是:

  • 之前做別的事情,對於一個作用域 具有在編譯器搜索至少有一個名爲Twice的實體,並列出候選人名單。 在這種情況下,名稱查找首先查看Calc的範圍,看看是否至少有一個名爲Twice的函數 ;如果沒有,基類 類和封裝命名空間將依次考慮,一個在 時間,直到找到至少有一個候選人的範圍。然而,在這個 的情況下,編譯器看起來的第一個範圍已經有一個名爲Twice的實體 - 實際上它有三個,所以 三重奏變成了候選集合。 (有關C++名稱 查找有關它如何影響你 應該打包的類和接口

  • 下一頁方式的更多信息,與討論中,編譯器執行重載解析挑選獨特 最佳匹配出來的在這種情況下,參數 是21,它是一個int,可用的重載需要一個double,一個 int和一個complex。顯然int參數是int參數 的最佳匹配(它是完全匹配且沒有轉換需要 ),所以選擇兩次(int)。

  • 最後,編譯器執行可訪問性檢查以確定 是否可以調用所選函數。

注意無障礙(由改性劑C++定義)和能見度是獨立的。可見性基於C++的範圍規則。一個班級成員可以是可見不可訪問在同一時間。

靜態成員作爲例子是全局可見通過您的應用程序的運行,但只針對應用到它們的改性訪問

1

作爲一個說明:(而不是一個struct其中成員默認都是公共的)在聲明class,範圍是默認私人

可變構件「X」是的,只有你的類訪問,它的朋友。沒有其他人可以直接訪問'x'(如果你有函數返回引用的話,它可以是間接的,這是一個非常糟糕的主意。)

你引用的文字談到了編譯器的可見性,所以X::x存在,不管是什麼。它不會消失只是因爲它是私人的。可見性用於查找您引用的成員,並返回匹配的第一個。在這一點上,編譯器會檢查可訪問性,如果可以訪問的話,你都很好。如果不是不合格

請注意,我提到的朋友。該關鍵字使所有可變成員都可訪問。當編譯器處理朋友時,它會完全忽略所有受保護的和專用的關鍵字。

在大多數情況下,這是一個非常簡單的過程。它按順序排列。期。

當你開始使用虛擬函數時,它們變得更加複雜:它們可以被公開,保護和私有,並且可以根據類聲明而變化...(A派生自B並且產生受保護的虛函數公共;它通常不是一個好主意,但C++並不妨礙你這樣做。)當然,這隻適用於函數,而不是可變成員,所以這是一個不同的主題。