1

請考慮以下鏈接列表類型類的示例代碼。我希望聲明一個返回一個迭代器的方法,它是的一個Node*。但是,Node是一個私有嵌套類,所以爲了使typdef,我需要讓編譯器知道有關前向聲明的Node。天真地說,我認爲這兩種都默認爲私人會工作;是這樣的:訪問說明符在typedef和前向聲明上的作用

class List 
{ 
    class Node; 
    typedef Node* Iterator; 
public: 
    List() : head_(NULL), tail_(NULL) {} 
    Iterator begin() {return head_;} 

private: 
    class Node 
    { 
     private: 
     int data_; 
    }; 

    Node* head_; 
    Node* tail_; 
}; 

int main() 
{ 
    List list; 
    List::Iterator = list.begin(); 
    return 0; 
} 

這4行導致編譯時錯誤:

'的typedef類List ::節點*目錄::迭代器' 是私人
編譯因終止 - Wfatal-錯誤。

這不是difficut明白爲什麼向前聲明class Node; private部分所屬,但對於typedef Iterator Node*;?這可能是因爲我對typedef關鍵字缺乏瞭解,但爲什麼要應用哪個訪問說明符?我認爲private更有意義,因爲Node類的可見性。

這是否與typedef s是公共接口的一部分?是否所有的typedefs都必須聲明爲public可見性?


編輯: 允許我澄清,我知道我可以從typedef的移動公衆抱怨阻止我的編譯器。我不明白的是爲什麼這是必要的。

+3

如果我在類定義的末尾添加一個分號,我不會收到任何錯誤。這是你的真實代碼嗎? –

+0

啊,所以它..這只是一個簡化版本。我會看看我是否可以重新創建錯誤 – StickyCube

+0

@StickyCube - 也許你正嘗試使用來自非朋友類/函數的'Iterator'類型? –

回答

1

您可以簡單地使typedef名稱成爲公共名稱。請嘗試以下

class List 
{ 
public: 
    typedef class Node* Iterator; 

而且考慮到這兩個類您忘記關閉括號後放置分號。:)

1

List::Iterator是私有的,所以不能使用的名稱,但類型可以推斷

List l; 
List::Iterator it = l.begin(); // Illegal 
auto it = l.begin(); // legal 

template <typename IT> 
void foo(IT it); 

foo(l.begin()); // legal 

順便說一句,您可能有List::Iterator公開,並保留List::Node私密。