静的データメンバーの初期化をクラス外にする必要があるのはなぜですか?
class X
{
public:
int normalValue = 5; //NSDMI
static int i;
};
int X::i = 0;
静的データメンバー(ここでは「i」)が定義ではなく宣言のみであるのはなぜですか?
「静的」クラス メンバーは、グローバルに割り当てられた変数のようなものです (単一のクラス インスタンスとは関係ありません)。そのため、何らかのオブジェクト ファイルに常駐する必要があります (「.cpp」ファイルで宣言する必要があります)。グローバル変数。
単純なクラス メンバー (非静的) は、クラス インスタンスに割り当てられたメモリ ブロックに常駐します。
単純な理由は、クラスは通常、複数の cpp ファイルに含まれるヘッダーファイルで宣言されるためです。静的データ メンバーには外部リンケージがあり、厳密に 1 つの変換単位で宣言する必要があるため、クラス内で定義するのには適していません。
juanchopanza が指摘しているように、次のことが許可されています。
struct A
{
const static int i = 1;
};
ただし、これは単なる宣言であり、定義ではありません。i
のアドレスをどこかで使用する場合は、まだ定義する必要があります。例えば:
f(int);
g(int&);
X<A::i> x; // Okay without definition for template arguments
char a[A::i]; // Okay without definition, just using value as constant expression
&A::i; // Need a definition because I'm taking the address
f(A::i); // Okay without definition for pass by value
g(A::i); // Need a definition with pass by reference
const列挙型のconst積分型の場合、宣言の時点で静的データメンバーを初期化できることに注意してください。
C ++ 03標準から、§9.4.2
静的データメンバーがconstintegralまたはconstenumerationタイプである場合、クラス定義でのその宣言は、整数定数式(5.19)である定数初期化子を指定できます。
struct Foo {
static const int j = 42; // OK
};