2013-04-05 5 views
16

に含めるので、クラスAを形成:は、前方宣言対ヘッダファイルに含めると、私はクラスBを持っている、と私はメンバーを呼び出したいの.cpp

1.

//A.h  
class B; 
class A 
{ 
private: 
    B* m_p; 
}; 

//a.cpp 
#include "B.h" 

2。

あまりにも依存度の低い小さなプロジェクトには、どちらの方が良いのですか?この2つは似ていますか?

+0

次のようにしてください: '#include" B.h "' –

+0

ああ、私は注意します... – colddie

答えて

23

それを行うのあなたの最初の方法はa.hで、class B存在が知られてではなく、その定義されていることを意味します。これにより、Bでできることがa.hに制限されます。たとえば、タイプの変数を持つことができますが、タイプBの変数はありません(タイプBの変数を宣言する場合、コンパイラはBの完全な定義を参照できるため)。また、タイプがB *の変数がある場合は、ポインタを逆参照できません(そのためにも、Bの定義を知っていなければなりません)。

したがって、これらの問題が発生していない–の2番目の選択–が優先されます。これはほとんどの人がほとんどの時間を使用しているためです。

これは、最初の方法が有用な場合のみです。

  • .hファイルがお互いにが含まれます(ただし、あなたはまた、-警備員について、さらに多くの問題を得ることができ、これは一般的に困難であり、避けることが)場合は、例えば:
  • b.hが非常に大きくて複雑な場合は、できるだけコンパイルプロセスが遅くなるため、できるだけそれを含めないでください。
0

クラスAのヘッダーにクラスを宣言するだけです。

class B; 
0

2番目の方が優れています。 Bクラスは、.hファイルを使用してインクルードするモジュールになります。将来、Bをサブクラス化し、Aを更新してCを使用する場合を考えてみましょう。 2番目のケースでは、ヘッダ#includeAのメイクだけを交換します。最初のケースでは、前方宣言を変更する必要があります。また、2番目のケースでは、シンボルB以上を定義します。

コメントのように、ヘッダファイルが残りのコードと同じディレクトリにある場合は、#include "B.h"を使用する必要があります。

何をやっているがdecleration前方呼ばれるまあ
0

、あなたはクラスBも場合にはクラスA

を使用して、クラスBを使用してクラスAのようなものを持っていた場合にはあるのでしょう理由あなたの2番目の選択肢を確実に使用できる関係は1つだけです。 二重使用が必要な場合は、クラスの少なくとも1つが減速を使用する必要があります。

7

回答:
は(デビッドKieras、EECS部門、ミシガン大学による)http://www.umich.edu/~eecs381/handouts/handouts.html

C Header File Guidelines

C++ Header File Guidelinesを見てみましょうと言う:#10

ガイドライン。 X型の宣言が不完全な場合は、ヘッダX.hを#includeする代わりに を使用します。別の構造体またはクラス タイプXが、 ヘッダーファイルの内容のポインタまたは参照タイプとしてのみ表示される場合は、Xhを#includeするのではなく、 Xの不完全宣言(「前方宣言) の近くのヘッダーファイルの先頭には、class X;が含まれています。 貴重なテクニックの詳細については、 Incomplete Declarationsを参照してください。標準ライブラリには、しばしば<iostream> ライブラリ(<iosfwd>)が必要な不完全な宣言のヘッダ が含まれています。できるだけ#<iosfwd>をインクルードしてください。 <iostream>ヘッダーファイルが非常に大きい(巨大なテンプレート!)ためです。

12

最初の方法は前方宣言です。2番目のクラスには実際にクラスBが含まれています。

たときに最初のものを使用してください:Aの定義

  • 、あなただけのBへのポインタを持っていますからBのいずれかの関数を呼び出すことはありませんB.
  • のすなわちないメンバー、 の定義のA(つまり、Bのメンバ関数へのすべての呼び出しは、実際にAのメンバ関数を実装する.cppファイル内で行われます)
  • クラスBのインターフェイスまたはサイズは頻繁に変更されますが、このようにして、Bが変化すると、 a.cppの内容は再コンパイルされますが、a.h(およびa.hを含む他のファイル)は変更する必要はありません。

利用秒1:

  • あなたは、コンパイラはそのクラス定義とそのすべてのメンバーのサイズを使用して、クラスのサイズを計算B.のサイズを知っておく必要があります。たとえば、クラスAがB型のメンバーを持つ場合、Aのサイズを計算するには、コンパイラはBのサイズを知る必要があります。 Bのサイズを知るには、b.hをインクルードする必要があります。
    • クラスBの関数を呼び出す必要があります。実際に存在する関数を呼び出すかどうかを知るには、コンパイラはクラスBのインタフェースを知る必要があります。つまり、b.hをインクルードする必要があります。
関連する問題