staticキーワードは、グローバル変数のスコープをその変換単位に制限します。 .hファイルでstatic int x
を使用し、その.hファイルを1つおきのファイルにインクルードすると、それらはすべて同じ翻訳単位に属しませんか?では、xはどこにでも表示されませんか?では、静的の役割は今何ですか?
また、static const int x
の使用法はありますか?xはグローバル変数ですか?すべてのconstグローバル変数はデフォルトで静的ではありませんか?また、const変数のスコープは、ファイル内のforループに限定されている場合でも、TUに制限されていますか?
あなたが書くなら
static const int x
。hファイルでは、#include-s this 。hであるすべての変換ユニットは、独自のプライベート変数x
を持ちます。 。
1つのグローバル変数をすべての人に表示したい場合は、次のように記述します。
extern const int x;
。hファイルと
const int x = ...;
。cppファイルの1つ。
静的constintを1つの変換単位だけに表示したい場合は、。hファイルで言及しないでください。
.hファイルでstaticint xを使用し、その.hファイルを1つおきのファイルにインクルードすると、それらはすべて同じ変換単位に属しませんか?
何かを静的として宣言した場合(クラス内ではなく、クラスの静的キーワードのセマンティクスが異なるため)、その静的変数はTUの外部では表示されません。したがって、ヘッダーファイルに配置すると、そのヘッダーを含む各TUは、その静的変数の異なるプライベートコピーを持つことになります。
また、const変数のスコープは、ファイル内のforループに限定されている場合でも、TUに制限されていますか?
番号。静的const値の場合でも、スコープはその宣言によって決定されます。したがって、スコープはブラケットの場合によって制限されます。
翻訳ごとにその変数のプライベートコピーが作成されることになり、そこに配置すると肥大化することになります。また、いたるところにランダムにコピーする必要があることも意味がありません。いいえ、それは大丈夫ではありません。
namespace
ブロックでconst int
を宣言できます。それで大丈夫です。
const
修飾された変数の観察可能な違いは、static
バージョンでは、変換単位ごとに1つのコピーを取得するため、そのような2つのコピーのアドレス比較が失敗する可能性があることです。
const
変数のアドレスを使用しない場合、最新のコンパイラーは値を使用して変数自体を最適化できるはずです。このような場合、static
const
修飾変数は完全に問題ありません。
基本的に、各ソースファイルとインクルードされたすべてのヘッダーファイルは単一の変換ユニットです。したがって、ヘッダーファイルに静的変数がある場合、ヘッダーファイルが含まれている各ソースファイル(翻訳単位)で一意になります。
「静的グローバル」は意味がありません、それらはある意味で互いに反対です。
「グローバル」という用語は、ファイルスコープの関数の外部で宣言された変数を表すために誤用されることがよくあります。むしろ、グローバル変数は外部リンケージの変数であり、プロジェクト内の任意のファイルからアクセスできます-したがってグローバルです。
外部リンケージの反対は内部リンケージです。これは、変数が宣言されている変換ユニットによってのみ変数にアクセスできることを意味します。 1つを意味する翻訳単位.c
ファイルとそれに含まれるすべてのヘッダー(再帰的に)。
static
は、変数が内部リンケージを取得することを保証します。したがって、他の翻訳はそれにアクセスしたり、それを参照するextern
変数を宣言したりすることはできません。
ヘッダーファイルでstatic
変数を宣言すると、複数の変換ユニットがその名前の個別の変数を取得します。コードは正常にコンパイルされますが、巧妙なリンカーはこれに気づき、リンカーエラーを出します。これらの種類のリンカーエラーは、多くの場合、説明的ではなく、追跡するのが困難です。
これにより、次のベストプラクティスが導き出されます。
このようなバグを防ぐために、常にすべてのヘッダーファイルを「ヘッダーガード」で囲んでください。
#ifndef MYHEADER_H
#define MYHEADER_H
/* contents of header */
#endif
ファイルスコープで宣言されたすべての変数は、プライベートカプセル化の目的で、名前空間の乱雑さを減らすために、static
で宣言する必要があります。同様に、extern
は、悪いデザインやスパゲッティプログラミングにつながるため、避ける必要があります。