グローバル変数が必要な場合。複数のコンパイル単位 (C++ ファイル) からアクセスできる単一の構造体:
/* foo.h */
#ifndef EXAMPLE_FOO_H
#define EXAMPLE_FOO_H
struct foo {
int a;
int b;
};
extern struct foo globalFoo;
#endif /* EXAMPLE_FOO_H */
--
/* foo.cpp */
#include "foo.h"
struct foo globalFoo = { 1, 2 };
--
/* bar1.cpp */
#include "foo.h"
int test1()
{
int c = globalFoo.b; //c is 2
}
--
/* bar2.cpp */
#include "foo.h"
int test2()
{
int x = globalFoo.a; //x is 1
}
foo.h の「struct {}」行は、構造体 foo がどのように見えるかをコンパイラに伝えます。「extern struct」行は、外部リンケージを持つ「globalFoo」と呼ばれる特定の構造体 foo を宣言します。(これらの 2 つの宣言を組み合わせることができます。@litb の回答を参照してください。) これが意味することは、globalFoo (bar1/test1 および bar2/test2) のユーザーが構造体を他の場所で探すことであり、独自の個別のコピーはありません。
foo.cpp は、globalFoo を定義する特殊なケースです。任意の変数の定義は 1 つしか存在できません。この場合、foo.cpp には globalFoo の定義があります。bar1 と bar2 が「外部」で globalFoo を探すと、foo.cpp の globalFoo が見つかります。この名前は、3 つのファイルすべてで同じ実際の構造体を参照します。
そこになかった場合、extern
3 つの .cpp ファイルすべてに「struct foo globalFoo;」という行が含まれます。(#include は単なるコピー/貼り付けであることを忘れないでください) それは、同じ名前の 3 つの異なる構造体を作成 [しよう] し、混乱を招きます。
注: " extern struct foo globalFoo;
" 行は foo.cpp の場合は冗長ですが、それは問題ではありません。