2016-05-06 20 views
1

が含ま入れ子になったクラスは、私はこのようになりますクラスを持つヘッダ

// Node.hpp 
template<typename T> 
class List<T>::Node { 
    ... 
}; 

私の質問があり、どのような各ファイルに含める必要がありますか、どこに#includeを配置しますか?

最も簡単な方法は、Node.hppの末尾にList.hppを含め、Node.hppには何も含めないことです。しかし、これによりNode.hppは完全なファイルではなくなります(IDEなどで開くと、List<T>の定義がないために多くのエラーが発生する)。また、ファイルの末尾に#includeを置いてもよいかどうかはわかりません。各ファイルを仮定し

がガード#defineを含め、独自のを持って、私はまた、(のIDEを幸せにするために)Node.hppの上部にList.hppが含まれ、その後、再びList.hppの底にNode.hppが含まれるが、それはだ場合、私は知らないことができます良い考え。

+0

あなたの疑問にお答えするには:同じファイルを2回含めると、あなたはどこでも好きな場所に '#incldue 'を置くことができます。 – MikeMB

+0

あなたが提案したことを行うことができます - 必要に応じて他の.hまたは.cppファイルに選択的に含めることもできます。これにより、node.hppを実際に使用している場所だけに変更するコンパイルの爆発半径をlist.hpp – xaxxon

+0

を含むすべてではなく減らすことができます。この配置例のライブ例は次のとおりです。https://godbolt.org/g/5c4HC7 – xaxxon

答えて

3

メンバー関数をList<T>::Nodeにコンパイルすると、コンパイラは常にテンプレート化されたクラスListの可視性を必要とします。その結果、Node.hppの内容の可視性を必要とする編集単位は、List.hppの内容(テンプレート化されたメンバーの定義)の可視性を必要とする。

最も簡単な選択肢はList.hppの末尾にNode.hppの内容を入れ、いずれかのテンプレートを必要とするコンパイル単位では#include "List.h"だけです。これにより、Node.hppの必要性が完全に排除されます。

実際に両方のヘッダー(List<T>::NodeList<T>のコンポーネントであるため、任意で無意味なようです)を含める必要がある場合、オプションはインクルードガードを支援することです。

// List.hpp 

    #ifndef LIST_HPP_INCLUDED // some unique macro 
    #define LIST_HPP_INCLUDED 

    // definition of templated class List 

    #include "Node.hpp" // this must be after the definition of List<T> 
    #endif 

とNode.hpp

// Node.hpp 

    #ifndef NODE_HPP_INCLUDED // some unique macro 
    #define NODE_HPP_INCLUDED 

    #include "List.hpp"  // this must precede the definitions for List<T>::Node 

    // definition of templated class List<T>::Node 

    #endif 

これは、いずれかの可能ヘッダーは、任意のコンパイル単位によって#include Dであること、及び含むガードは無限の再帰を含む停止。

ほとんどの現代のIDEがこれに対応しています。あなたが持っていないものがあれば、単純に単一のヘッダファイルに移行します。

+0

私は 'Node.h'を' List.hpp'をよりきれいにするために独自のファイルに分けたいと思いましたが、必要ではないと言っています。 –

+0

また、私が( 'List List :: Node {...}'を 'List.hpp'の最後に置いて)提案したように、' List'の中に 'Node'を定義することはできません直接? –

+0

まあ、はい。 'Node'は' List 'のネストされたクラスです。ネストされたクラスの定義(テンプレート化されているかどうか)は、包含クラスの定義内に置くことができます。 – Peter

関連する問題