2012-11-06 86 views
2

可能重複:
Pros and cons of using nested C++ classes and enumerations?內部類聲明

考慮以下聲明。

class A { 
    public: 
    class B{ 
    }; 
}; 

沒什麼特別的。

  • 但這樣有什麼好處呢?
  • 將一個課程放入另一個課程的原因是什麼?
  • 這兩個類別之間沒有繼承權益。
  • 如果B是把裏面的私人名共享,則A是對於B只是一個命名空間,有理由使B私人,太。

你覺得這個怎麼樣?

回答

4

從概念上講,它可以讓程序員知道B類與A類特別相關。當你在類A之外使用B類時,你必須使用類型A :: B,它每次都會提醒你,B與A相關。這不會添加任何功能,但會顯示關係。

同樣,你不必在所有使用繼承/組合,或類。只需使用結構和函數即可模擬C語言中的類。這只是一種保持代碼更清晰,更直接的方法,讓程序員可以更輕鬆地將代碼與設計聯繫起來。課程比公共小類做得更多,但這只是一個例子。

如果它是一個私有/受保護的子類(我認爲它不在你的例子中),那麼顯然限制該類實現該類和該類的子類,這可能是期望的(再次設計方面)如果該類的唯一用例在該類的實現中(以及可能的子類)。

+0

所以,你要堅持這樣一個觀點,即這樣的構造允許將A僅用作B的名稱空間。正確? – OlegG

+0

據我所知,是的。 –

0

可能是什麼原因把一個類裏面另外一個?

  • 如果您需要限制B的範圍僅適用於A,那麼內部類定義將有所幫助。因爲它將類範圍限制在本地。這是調用範圍本地化。這些更通用的術語叫做inner class declaration。檢查這個link
  • 此計算器question幫助您瞭解更多。
+1

在這種情況下,B適用於任何想要使用它的人。因爲它是A.的公共成員。 – OlegG

+0

但是,如果B在A之外,那麼它不能訪問A的私人成員(除非你聲明爲朋友)。檢查此鏈接 - http://stackoverflow.com/questions/3791296/is-there-any-difference-between-a-public-nested-class-and-a-regular-class –

1

好處1:命名空間方面

事實上,A提供B一個命名空間,這可以幫助我們構建我們的代碼要好得多。考慮一個vectorAiteratorB的具體示例。可以說,

class vector { 
public: 
    class iterator { /*...*/ }; 

    iterator begin() { /*...*/ } 
}; 

是更容易輸入,閱讀,理解比

class vector_iterator { 
    /*...*/ 
}; 

class vector { 
public: 
    vector_iterator begin() { /*...*/ } 
}; 

觀察,特別是:

  1. 當兩個類(vectoriterator)依賴彼此之間,即使用彼此的成員,上面的第二個版本將要求兩個之一被前向聲明,並且在某些情況下,相互類型依賴可能導致unresol虛擬情況。 (使用嵌套類,這是很容易避免這樣的問題,因爲嵌套類定義的大部分地區內,外類被認爲是完全定義。這是由於第9.2節/ 2。)

  2. 您可能還有很多其他數據類型可以維護自己的iterator,例如linked_list。使用上面的第二個版本,您需要將linked_list_iterator定義爲單獨的類。類名會變得越來越長,並且複雜化更多這些「依賴」類型和您添加的替代類型。

優點2:模板

繼續上面的示例,現在考慮一個函數模板,需要一個容器(如vectorlinked_list定義同上)作爲參數,並遍歷它們:

template <typename Container> 
void iterate(const Container &container) { 
    /*...*/ 
} 

在這個函數裏面,你顯然非常想使用迭代器類型Container。如果這是一個嵌套的類型,很容易:

typename Container::iterator 

但是,如果不是的話,你將不得不採取迭代器類型作爲一個單獨的模板參數:

template <typename Container, typename Iterator> 
void iterate(const Container &container) { 
    /*...*/ 
    Iterator it = container.begin(); 
    /*...*/ 
} 

如果這迭代器類型沒有出現在函數參數中,編譯器甚至無法猜測類型。每次調用iterate函數時,都必須明確將其添加到尖括號中。

最後說明:這與嵌套類是聲明爲public還是private是無關的。我上面的例子提出了一種公共嵌套類型顯然是可取的情況,因爲我認爲iterator類型應該能夠在容器類之外使用。