私の C++ プロジェクトでは、ヘッダー ファイルでグローバル変数を宣言すると、Visual Studio 2012 で LNK2005 (x は既に y.obj で定義されています) および LNK1169 (1 つ以上の乗算定義されたシンボルが z.exe で見つかりました) エラーが発生しますが、 const識別子でグローバル変数を宣言すると、エラーは発生しません.msdnでの調査から、プロジェクトのプロパティが原因であることがわかります.しかし、プロパティで修正することはできません.const識別子でのみ修正されます.しかしC++ でそれに関するルールを見つけることができません。C++11 の新機能ですか?
1 に答える
これはグローバル変数の宣言です:
extern int my_global;
Thie は、グローバル変数の定義です。
int my_global;
グローバル変数の宣言は、「ここにオブジェクトの名前があります」と言います。定義には、「ここにオブジェクトの名前があり、それにストレージスペースを割り当ててください」と書かれています。
グローバル変数の宣言は必要な数だけ持つことができます (そのため、任意のソース ファイル内の誰もが同じオブジェクトを参照できます) が、定義できるのは 1 つだけです。プログラムが実行されます。
リンカーは、ヘッダー ファイルに定義を入れているため、同じオブジェクトの複数の定義があり、そのヘッダーが複数のソース ファイルに含まれていると不平を言っています。そのため、これらのソース ファイルがコンパイルされると、複数の定義が取得されますが、リンカーはそれを行うことができません。
解決策は、ヘッダー ファイルに宣言のみを配置し、定義を1 つのソース ファイルに配置することです。例えば:
// MyVariables.h
extern int my_global;
// MyVariables.cpp
int my_global = 42;
const
キーワードで異なる動作が見られる理由は、const
がグローバル変数に内部リンケージを与えるためです。つまり、他のソース ファイルからは見えないということです。実際、これらは、ヘッダーを含む各ソース ファイルが独自の定数のコピーを取得することを意味します。これはもう少しメモリを消費しますが、目立たないでしょう。これは定数なので、異なる定数がメモリ内の異なる場所を参照していることに誰も気付かないでしょう。
C++11 は、この動作を変更しませんでした。これらのコンストラクトはすべて、以前のバージョンの C++ では同じように動作しました。