23

ヘッダーファイルの使用法について、次の疑問があります。

1 - コメントの後に配置するガードを含める

/* Copyright Note and licence information (multiple lines) */
#ifndef FOO_H
#define FOO_H
// Header file contents
#endif

Herb Sutter は、著書「C++ コーディング標準」の中で、上記のようなコードには問題があると述べています。彼は、「#ifndef」ステートメントはヘッダー ファイルの最初の行に表示する必要があると言っています。私はこれを説得力があるとは感じていません。これはヘッダーファイルの皆さん/ギャルが続きますか?

2 - ヘッダー ファイルで名前空間を使用する

#ifndef FOO_H
#define FOO_H
namespace FooNameSpace{
    // Header file contents
}
#endif

上記のコードは正しい慣行を使用していますか? つまり、ヘッダー ファイルで名前空間を使用しますか? ヘッダー ファイルに名前空間をインポートすることが無意味である理由はわかっていますが、上記のような宣言はどうでしょうか。

上記の方法が正しい場合、別の名前空間にあるクラスの「前方宣言」をどのように行うのですか? のようですか

#ifndef FOO_H
#define FOO_H
namespace AnotherNameSpace{
    class AnotherFoo; // forward declaration
}

namespace FooNameSpace{
    // Use AnotherFoo here
}
#endif

「循環依存」を回避する唯一の方法は「前方宣言」ですね?

4

5 に答える 5

19
  1. インクルード ガードとコメントの順序は、純粋にスタイルの問題です。コンパイルの速度に測定可能な影響はありません。

  2. 名前空間は、関数、クラス、グローバルなどを宣言するために、ヘッダー ファイルで絶対に使用する必要があります。ヘッダー ファイルでステートメントを使用してはなりませんusing。それを含むソース ファイルで何かを使用解除することは不可能です。グローバルスコープに余分なものを追加するためのインクルーダー。ヘッダーで他の名前空間のものを使用する必要がある場合は、すべての名前を完全修飾します。時には苦痛になることもありますが、それは本当に正しいことです。

例:

// WRONG!
using namespace std;
class MyClass
{
    string stringVar;
};

// RIGHT
class MyClass
{
    std::string stringVar;
};

他の名前空間でのクラスの前方宣言については、まさにそのとおりです。ヘッダー内で参照するときは、常に修飾することを忘れないAnotherFooでください。AnotherNameSpace::AnotherFoo実際、前方宣言は、循環依存を解消する唯一の方法です。

于 2009-01-04T05:49:17.617 に答える
7
  1. インクルード ガードの前にコメントがあると、一部のコンパイラが最適化を見逃す可能性があると聞いたことがあります。ガードが最初のものである場合、コンパイラはイディオムを認識し、後続のインクルードのためにヘッダーを開くことさえしません。私自身のコードでは、通常、コメントはインクルード ガードの前に置かれます。これが影響を与えるかどうかをテストすることを気にしたことはありません。そして、私はおそらくそうするつもりはありません(しかし、他の誰かがそうするなら、私は結果に興味があります).

  2. もちろん、ヘッダーには名前空間を組み込む必要があります。そうしないと、名前空間内に有用なものは何もありません。usingただし、前述のように、ヘッダーは名前空間を「 」ディレクティブを使用してコンパイル単位に「インポート」(より適切な言葉が必要なため) しないでください。

于 2009-01-04T05:59:56.673 に答える
3

1 については、具体的な賛否両論を認識していません。多くの企業では、著作権表示をファイルの最初の項目として、他のコードや意味のあるコードよりも前に置く必要があるという方針をとっています (おそらく、コードを理解する前に著作権を読むことを前提としています)。そのために、#IFNDEF は既にコードになっています。ユーザビリティの観点からは、目は著作権を無視するため、著作権を最初に置くことは理にかなっています。ただし、私の意見では、モジュールを説明するものは #ifndef の後に来る必要があります。

于 2009-01-04T05:54:08.103 に答える
2

1) コメントは実際には何もしないので、あまり重要ではないと思います。ただし、技術的には、#include のコピーと貼り付けが行われるため、コメントをヘッダー ガードの外側に配置すると、プリプロセッサの作業が増える可能性があります。ほとんどのコンパイラがこれを最適化するのに十分賢いかどうか (つまり、プリプロセッサ ステップの前にコメントを削除するかどうか) はわかりませんが、数万のヘッダー ファイルに到達するまでおそらく気付かないでしょう。

2) その通りです。クラスを名前空間内に配置したい場合、そのクラスがヘッダー ファイルで宣言される場合は、名前空間内で宣言する必要があります。つまり、ヘッダー ファイル内にある必要があります。はい、それがあなたが正確に宣言する方法です。はい、それは循環依存を回避するための主要なツールです (設計を変更することもできますが、問題の 2 つのクラスが参照またはポインターによってのみ相互に参照し、メソッドを呼び出さない限り、原則として循環性に問題はありません)。 .

于 2009-01-04T05:54:59.570 に答える
2
  1. この投稿に対する Adam の回答で指摘されているように、コメントを追加してもパフォーマンスに影響はないと思います。

  2. ヘッダー ファイルで自分自身の名前空間を使用しました。独自の文字列クラスを定義すると、std 名前空間の文字列クラスと衝突します。

「using」キーワードを正確に使用することは間違いではありません (すべての変数の前に入力する手間が減り、利便性が大幅に向上するため)

于 2009-01-04T06:03:02.113 に答える