2010-05-24 64 views
1

我在這裏有一些疑問。希望你們可以分享一些編程技巧。只是好奇地想知道,如果我按照下面的代碼進行操作,是不是一種很好的編程習慣。內部類的任何解決方案或編程提示?

class Outer { 
public: 
    class Inner { 
    public: 
     Inner() {} 
    } 

    Outer() {} 
}; 

我一直在做這結構,我只希望我的結構被暴露在我的課,而不是全球性的。但這裏的情況有所不同,我現在正在使用一堂課?你們以前面對過這種情況嗎?非常感謝你的任何建議;)

回答

0

這不是一個日常事物,但它也不是聞所未聞的。如果在客戶端使用Outer時有一個只對客戶端程序有意義的類(Inner),您可以這樣做。

0

如果您只希望在某個文件中公開某個類,則可以使用該文件中的一個未命名的名稱空間。然後,該名稱空間內的任何代碼僅在該文件中可用。

namespace 
{ 
    //stuff 
} 
2

我會打破答案分爲兩個部分:

  1. 的情況下,你只組織代碼,您應該使用的類的命名空間 - 如果內部類是不是一個實體只能在類內部使用(特別是只在類中構造),那麼內部類是一個好主意 - 另一個示例STL函數對象。
  2. 在C++中,結構和類之間絕對沒有區別,除非結構默認具有公共成員。因此,當你有課時,沒有什麼真正的區別 - 這更多的是風格問題。
2

在許多情況下,這是一個很好的做法。這裏有一個我們實現鏈接列表:

template <class T> 
class MyLinkList { 
    public: 
class Node { 
    public: 
    Node* next; 
    T data; 
    Node(const T& data, Node* node) : next(node), data(data) {} 
}; 

class Iterator { 
    public: 
    Node* current; 
    Iterator(Node* node) : current(node) {} 
    T& operator*() { return current->data; } 
    void operator++(int) { current = current->next; } 
    bool operator!=(int) { return current != NULL; } 
}; 

    private: 
Node* head; 

}

以上僅僅是摘錄的是不打算完整或編譯的。重點是要顯示Node和Iterator是MyLinkList類的內部類。之所以這樣做是有道理的,是爲了傳達這樣一個事實,即Node和Iterator不是獨立的,而是需要由MyLinkList進行限定(例如MyLinkList :: Iterator它

+0

你能告訴我一個理由節點是公共的,揭露的實施? – 2010-05-24 03:00:17

+1

如果我沒有記錯,如果Node和Iterator是私有的,編譯器可能會導致錯誤,如果它看到像** MyLinkList ::節點**或** MyLinkList :: Iterator它**。我希望傳達一點,Node和Iterator應該只在MyLinkList的上下文中有意義,而不是我自己,我認爲這是問題的實質。 – 2010-05-24 03:20:11

2

這是純粹是一種風格問題,但我認爲在C++社區中使用名爲detail的名稱空間對於純粹是幫助程序的類或純粹用於其他類的實現的類型通常更常見。使用名稱空間代替內部類有幾個優點,其中包括:更大的兼容性(例如,編譯器在內部類中解析名稱的方式在Visual C++和GCC之間可能會有令人難以置信的差異),更多的封裝(在內部/外部變體中,內部類可以更好地訪問外部類實例的成員),更簡單的實現(您不必在實現文件中每次都完全限定幫助器類,因爲您可以在其中放入使用指令。 cpp「源文件)。如果您打算使用內部類,那麼您需要做出有意識的決定,將其作爲API的一部分。

使用命名空間

namespace collection 
{ 
    namespace detail 
    { 
     class LinkedListNode 
     { 
      //... 
     }; 
    } 

    class LinkedList 
    { 
      // ... 
    }; 
} 

使用內部類

namespace collection 
{ 
     class LinkedList 
     { 
      // ... 
      class LinkedListNode 
      { 
       // ... 
      }; 
      // ... 
     }; 
} 
+0

謝謝你的例子,但我有點困惑。讓我們假設我正在實例化LinkedList對象,並且我只希望LinkedList對象與LinkedListNode有聯繫。沒有其他人(從LinkedList對象驅動的程序員或子對象)。我一直在考慮將LinedListNode分離爲其他文件(.cpp或.h),但只是擔心其他程序員會在未經我許可的情況下嘗試實例化它。命名空間會幫助解決這個問題?預先感謝;) – huahsin68 2010-05-25 03:28:57

+0

@ huahsin68,如果你正在使用模板,那麼你可以做的很少,使它完全隱私,因爲聲明需要可見。但是,如果你不是,那麼你可以在你的LinkedList聲明中使用void *而不是LinkedListNode *(你的實現必須強制轉換),並且你可以將LinkedListNode放置在你的「.cpp」實現文件中的一個匿名命名空間中。也就是說,在C++社區中很好理解,名稱空間「detail」包含可能會更改的實現細節,並且...... – 2010-05-25 21:39:19

+1

...使用名稱空間「detail」的元素(如使用未記錄的功能)擔保和一個使用這些項目的人自己的危險。 – 2010-05-25 21:41:29