2009-05-07 22 views
9

フォワード宣言を使用し、実装ファイルに#includeを移動することで、一連のヘッダファイル "include spaghetti"を単純化しようとしています。しかし、私は次のシナリオを続けます:フォワードは、C++でクラスのパブリックなtypedefを宣言します

//Foo.h 
#include "Bar.h" 

class Foo 
{ 
public: 
    void someMethod(Bar::someType_t &val); 
}; 

//Bar.h 
. 
. 
. 
class Bar 
{ 
public: 
    typedef std::vector<SomeClass> someType_t; 
}; 

できるだけ多くの場合、#include "Bar.h"を削除します。 Bar.hのtypedefがBarクラスの外にリストされている状況もわかります。私は両方の状況が同じように対処できると仮定しています。

アイデア?

+0

バーは本当にクラスかテンプレートですか? Barがテンプレートの場合、つまりBarが一意でないため、Bar :: someType_tも一意でない場合、答えは異なります。 –

答えて

8

残念ながら、多くの選択肢がなく、完璧ではありません。

まず、2つの明らかと許容できない解決策:

  • あなたは完全にtypedefを使用しての目的に反しtypedefを宣言転送することができます。
  • 避けたいファイルtypedefが含まれています。

より興味深いソリューション:

  • は同じで、すべての関連typedef sが含まれ、そのファイルが含ま持っています。これは、クラス間のコード結合を作成します。関連するクラスでのみ行うべきです。さもなければ、あなたは神のインクルードファイルで終わるつもりです。このファイルにtypedefを追加すると、多くの再コンパイルが行われる可能性があります。
  • 各クラスには、typedefを含む別のインクルードがあります。一種の迷惑ですが、機能します。

最後の2つは前方宣言のようですが、typedefが追加されています。 typedefファイルを変更することはめったにないので、ファイルの相互依存関係を軽減します。

ほとんどの場合、セントラルインクルードは面倒な点で最も効果があります。ちょっと注意してください。

+1

私は4番目のオプションを実行する可能性があります: - Foo.hで同じ正確なtypedefを宣言します 私の推論は、Fooが独自のインターフェイスをクライアントに提示していることです。クライアントソフトウェアはbar.hをインクルードする必要はありません。このレベルのカプセル化と低結合は私が目指しているターゲットです。 –

+0

私は5番目の選択肢を言うつもりだった。 –

-2

class Bar;をそのまま使用してください。それはC++にあなたがBarを定義する意図を宣言していることを伝えます。

+1

'class bar'内のtypedefに注意してください...これは本当の問題です、あなたが提案した前方宣言で対処できるクラスそのものではありません。 – Naaff

関連する問題