クラスBがあり、クラスAのメンバーを呼び出したいので、
1。
//A.h
class B;
class A
{
private:
B* m_p;
};
//a.cpp
#include "B.h"
2。
// A.h
#include "B.h"
class A
{
private:
B * impl_;
};
どちらの方法が優れているか、依存関係があまりない小さなプロジェクトが関係する場合、この2つは似ていますか?
それを行う最初の方法は、a.h
でclass B
の存在はわかっているが、その定義。これにより、a.h
内でB
を使用して実行できることが制限されます。たとえば、タイプB *
の変数は使用できますが、タイプB
の変数は使用できません(タイプB
の変数の宣言の場合、コンパイラはコンパイラを参照できる必要があるため) B
の完全な定義)。また、B *
型の変数がある場合、ポインターを逆参照することはできません(そのためにも、B
の定義がわかっている必要があるため)。
したがって、これらの問題のない2番目の選択肢が推奨され、ほとんどの人がこれを使用します。
これは、最初の方法が役立つ特殊なケースにすぎません。例えば:
.h
ファイルに他のが含まれている場合(ただし、インクルードガードに関しても、さらに多くの問題が発生する可能性があります。これは通常、難しく、避けるべきです);b.h
が非常に大きく複雑な場合、コンパイルプロセスの速度が低下するため、可能な限り含めないでください。最初の方法は、前方宣言です。 2番目には実際にクラスBが含まれています。
どちらを使用するのですか?
回答:1。
ご覧ください http://www.umich.edu/~eecs381/handouts/handouts.html
Cヘッダーファイルのガイドライン
C++ヘッダーファイルガイドライン (ミシガン大学EECS部、David Kieras著)は次のように述べています。
ガイドライン#10。 X型の宣言が不完全な場合は、ヘッダーを含む#.hの代わりにそれを使用してください。別の構造体またはクラス型Xがヘッダーファイルのコンテンツでポインターまたは参照型としてのみ表示される場合は、#include Xhではなく、Xの不完全な宣言(「前方」宣言とも呼ばれる)をヘッダーファイルの先頭。例:
class X;
この強力で価値のある手法の詳細については、配布資料 不完全な宣言 を参照してください。標準ライブラリには、<iostream>
という名前の<iosfwd>
ライブラリによく使用される不完全な宣言のヘッダーが含まれていることに注意してください。 #include<iosfwd>
<iostream>
ヘッダーファイルは非常に大きい(巨大なテンプレート!)ため、可能な場合はいつでも使用できます。
クラスAのヘッダーでクラスを宣言するだけです。
class B;
2番目の方が優れています。 B
クラスを、.h
ファイルを使用してインクルードするモジュールにします。将来的にB
をサブクラス化し、A
を使用してC
を使用するように更新する場合を考えます。 2番目のケースでは、ヘッダー#include
およびA
のメイクアップのみを置き換えます。最初のケースでは、フォワード宣言を変更する必要があります。また、2番目のケースでは、シンボルB
以外のものも定義します。
そして、コメントのように、ヘッダーファイルが残りのコードと同じディレクトリにある場合は、#include "B.h"
を使用する必要があります。
さて、あなたがしていることは前方デクレレーションと呼ばれます、あなたが望む理由は、クラスBを使用するクラスAとクラスAを使用するALSOクラスBのようなものがある場合です。
リレーションが1つしかない場合は、2番目の選択肢を使用できます。二重使用が必要な場合は、クラスdeclerationの少なくとも1つが前方declerationを使用する必要があります