4

.cppファイル間の変数アクセスがどのように機能するかについて少しあいまいです。例えば:

main.cpp

int main()
{
    int a = i;
    return 0;
}

main2.cpp

int i;

これにより、main.cppでコンパイラエラーが生成され、iに存在しないことが通知されます。では、「static」キーワードはこのコンテキストでどのような違いがありますか?(私はそれのためにグーグルを試しましたが、ほとんどの「静的キーワード」情報ページはクラスと関数について話します)

main2.cpp

static int i;

同じですか?extern int i他の場所へのアクセスに使用されるのを防ぎますiか?匿名の名前空間の使用は、変数の処理方法がどのように異なりますか?

main2.cpp

namespace
{
    int i;
}

総括する:

  • .cppファイル間で変数にアクセスできますか?(externキーワードは別として)
  • グローバル変数のstaticキーワードはどのように影響しますか?
  • 匿名の名前空間はどのように物事に異なる影響を与えますか?
4

3 に答える 3

3

最初の例では、の宣言がそのファイルに含まれている場合にアクセスできmain2.cppた可能性のあるグローバル変数を定義iします。(通常、そのextern宣言はヘッダーファイルから取得されます。)で宣言されたことがないため、コンパイラエラーが発生しました。これは、コンパイラがそのような変数がないと想定していることを意味します。main.cppexterniimain.cpp

2番目の例でmain2.cppは、ファイルスコープ変数を定義しますi。ファイルスコープ変数は、たとえ同じ名前であっても、グローバルとは異なります。i2番目の例でinのextern宣言があった場合main.cpp、両方のファイルは正常にコンパイルされますが、グローバル変数iが定義されていないため、リンクエラーが発生します。

main2.cpp2番目の例からに名前を変更しmain3.cpp、の外部宣言を追加し、i3main.cppつすべてをコンパイルし、それらをすべてリンクすると、成功します。main.cppとmain2.cppはi、という名前の1つの変数を共有し、。という名前main3.cppの独自の完全に別個の変数を持ちますi

このようなものはリンケージと呼ばれます。名前空間は、リンケージとはほとんど完全に無関係です。ただし、匿名の名前空間は特別です。匿名の名前空間で変数を定義することは、すべての実用的な目的で、それをで定義することと同じstaticです-それはそれをファイルスコープ変数にします。(私が正しく覚えていれば、違いはありますが、エクスポートされたテンプレートで複雑なことをしている場合にのみ問題になります。エクスポートされたテンプレートはほとんど使用されていないため、C++標準から機能を削除することについて話しているのであなたはしません。心配する必要はありません。)

匿名名前空間の価値は、その中にクラス定義を入れることができ、それによってクラスのすべてのメソッドがファイルローカルになることです。(この効果を得るには、ブロックのみがclass { ... }ブロック内にある必要がありnamespace { ... }ます。)他の方法でそれを行うことはできません。

于 2010-09-07T19:59:32.853 に答える
1

すべてのグローバル変数には、ある種のリンケージがあります。extern異なるファイル間の異なるコンテキストで同じ変数に名前を付けるには、リンケージが必要です。

externデフォルトです。実際にextern変数宣言で使用する場合は、別のファイルへの参照として扱われます。実際に変数を作成するには、リンケージ指定子を省略します。これは1つのファイルでのみ発生する必要があります。

extern int i; // i exists somewhere in some .cpp file.
int i; // ah! this is the file it exists in. 
       // (Although nothing special about that.)

staticグローバル(名前空間スコープで)に適用すると、ファイルに対してローカルになります。プライベート名前空間からも同じ効果が得られるため、static外部関数またはクラススコープは非推奨になりました。しかし、多くの人はまだそれを使用しています。

staticfile-localを意味する規則の例外は、クラスとinline関数にあります。セマンティクスは同じであるため、クラスstaticメンバーをより適切に呼び出す必要があります。醜くて紛らわしいですが、Bjarneはキーワードとしてextern削除したかっただけだと思います。extern

インライン関数は複数の.cppファイル間で同じ定義を持つことができるため、変数を作成するstaticと、変数の定義も共有されます。

于 2010-09-07T19:50:16.313 に答える
0
  • はい、たとえば静的クラス変数を使用できます
  • 変数をローカルにし、コンパイル単位に対して永続的にします
  • 匿名の名前空間は、シンボル間の衝突を防ぎます。一意の名前空間を手動で作成するかのようです
于 2010-09-07T19:51:29.770 に答える