12

効果的な C++ (第 3 版) の項目 31 で、Scott Meyers は、クラスが従来の宣言 (.h) および定義 (.cpp) ファイルに加えて、前方宣言インクルード ファイル (fwd.h) を持つ必要があることを示唆しています。完全な定義を必要としないクラスは、自身を前方宣言する代わりに使用できます。

私はそれのケースをいくらか見ていますが、これを実行可能なオプションとは本当に思いません...維持するのは非常に難しく、かなりやり過ぎで、ほとんど必要ではないようです。

ただし、かなり重いテンプレートの前方宣言に使用されていることがわかります。しかし、単純なクラスの場合は?維持するのは苦痛であり、非常に小さな目的を果たすほとんど空のインクルードファイルを大量に作成するようです...手間をかける価値はありますか?

次に例を示します。

// Class.h
class Class
{
    Class();
    ~Class();
};

// ClassFwd.h
class Class;

// Class.cpp
Class::Class()
{
}

Class::~Class()
{
}

私の質問:

皆さんはどう思いますか?これは良い習慣ですか?

: 私は主に、この慣行の議論に関心があります。Scott Meyers に同意させる何かを見落としていないかどうかを確認するためです。

4

4 に答える 4

7

すべてのライブラリで前方宣言ヘッダー ファイルを使用しました。ライブラリは通常、次の構造を持ちます。

lib/
  include/
    class headers + Fwd.h
src/
  source files + internal headers

ディレクトリには、lib/include1 つの前方宣言ヘッダーとともに、すべてのパブリック クラス ヘッダーが含まれます。これにより、ライブラリはインクルード側で軽量になりました。このライブラリの外部のヘッダーには、転送ヘッダー ( Fwd.h) のみが含まれますが、このライブラリの外部のソースには、必要な完全なヘッダーが含まれます。Lib.hソースファイルで使用するために、他のすべてのヘッダーを含む便利なヘッダー ( ) を提供することもできます。

前方宣言ヘッダーに配置するもう 1 つのことは、typedeffor ですshared_ptr。特に、実装へのポインターを返すファクトリ クラスを含む継承階層の場合です。

上記は、多くの内部ライブラリを持つ大規模なアプリケーションに役立ちます。この場合の上記の改良は、パブリック ヘッダーを に配置することlib/include/libです。このようにして、ライブラリのクライアントは を含める必要がありますlib/...。これは、ヘッダーの名前空間と考えてください。

幸運を!

于 2010-10-14T16:38:59.150 に答える
2

シンプルclass Whatever;を独自のヘッダーに配置しても、長所はなく、多くの短所があります。

特にヘッダーへのアクセスに時間がかかる場合は、単純な前方宣言を使用してヘッダーへのアクセスを回避します。それらを独自のヘッダーに配置すると、目的が無効になります...

テンプレート化されたものでは、ご存知のように、それは別の問題です。<iosfwd>たとえば、標準ライブラリからチェックアウトします。

乾杯&hth。

于 2010-10-14T16:11:59.007 に答える
1

この方法により、コードユーザーはクラスが通常かテンプレートかを考えないようになります。ユーザーは「corresponding_fwd.h」ファイルを#inludesするだけで、クラス参照があります。ユーザーにとってもう1つの煩わしさは、AGoodThingです。しかし、それが小さなプロジェクトであるか、クラスの作成者が唯一のクラスのユーザーである場合、それはより厄介かもしれません。だから、それは異なります。

于 2010-10-14T16:15:24.677 に答える
0

大規模なソリューションがある場合、これが固有の依存関係を処理する唯一のチャンスです。

struct A {
    B* m_pB;
};

struct B {
    A* m_pA;
};

現在、A と B は、別のヘッダー ファイル、場合によっては別のプロジェクトにある可能性があります。それでも、それらの依存関係は設計上の欠陥ではなく、完全に論理的で必要なものです。職業はなんですか?

  1. 最初に、必要なプロジェクトごとに単一の Types.h 前方宣言ヘッダーを含めます。つまり、前方宣言には、クラスごとに独自のヘッダー ファイルがありません。
  2. 次に、必要なすべてのプロジェクトの Class.h を含めます。これらのヘッダーをコンパイルするには、前方宣言が必要です。
  3. メイン プロジェクトのヘッダーを含めます。

かなり大規模なソリューション (500k LOC) では、このパターンは非常に簡単に管理できることがわかりました。それ以外の場合、クラス宣言を変更した場合、他のヘッダー ファイルで個別に行ったすべての前方宣言はどこにありますか?

于 2010-10-14T16:09:06.270 に答える