クラスがある場合:
Object.h
class Object
{
public:
static int number;
};
オブジェクト.cpp
int Object::number = 5;
のスコープは、作成されたObject::number
インスタンスのスコープよりも長持ちすることが保証されていObject
ますか? 別のソースファイルでグローバルに宣言されている場合でも?
クラスがある場合:
Object.h
class Object
{
public:
static int number;
};
オブジェクト.cpp
int Object::number = 5;
のスコープは、作成されたObject::number
インスタンスのスコープよりも長持ちすることが保証されていObject
ますか? 別のソースファイルでグローバルに宣言されている場合でも?
はい、「静的ストレージ期間」があります。これは、「常に」存在することを意味します[非標準のコンストラクターがある場合、コンストラクターは「メイン」が開始する前に呼び出されます-ほとんどの意図と目的には十分なはずです]
並べ替えですが、それint
は特殊なケースだからです。たとえば、次のように記述したとしますObject.cpp
。
Object o = {};
int Object::number = 5;
次に、オブジェクトo
には静的な保存期間がObject::number
あります。名目上は前に作成されnumber
、後で破棄されますが、どちらも POD であるため、この破棄は実際には効果がありません。
number
ただし、とo
に重要なデストラクタがある場合は、 の前number
に破棄されo
ます。number
がクラスの静的メンバーであるという事実はo
、破棄の順序に関する限り、特別な扱いを与えません。
が別のソース ファイルでオフの場合o
、構築の順序は指定されず、破棄の順序は構築の逆順になります (繰り返しますが、重要なデストラクタint
がある場合です。そうでないため、特殊なケースです)。
はい、次の 2 つの理由からです。
つまり、ユーザー定義コード (静的オブジェクトのコンストラクターを含む) が実行される前に、静的初期化フェーズで初期化されることを意味します。したがって、コードがアクセスできるようになる前に、存在し、初期化されることが保証されます。
コンストラクターまたは非定数イニシャライザーがある場合は、他のすべてのそのようなオブジェクトと共に動的初期化中に初期化されます。その場合、別の静的オブジェクトのコンストラクターまたは初期化子が、初期化される前にオブジェクトにアクセスする可能性があります。この問題は、「静的初期化順序の失敗」と呼ばれることもあります。
次の g++ プログラムを検討してください。
#include <iostream>
#define X() (std::cout << __PRETTY_FUNCTION__ << "\n")
struct M {
M() { X(); }
~M() { X(); }
};
struct C {
C() { X(); }
~C() { X(); }
static M m;
};
C c;
M C::m;
int main () { X(); }
このプログラムでは、 のc
前に初期化するC::m
必要があり、 の後に破棄する必要がありますC::m
。このプログラムをコンパイルしてその出力を検討すると、次のようになります。
C::C()
M::M()
int main()
M::~M()
C::~C()
したがって、いいえ、一般的に、「[メンバー]の [ライフタイム] は、作成されたオブジェクトのインスタンスの [ライフタイム] よりも長持ちすることが保証されていませんか?」
静的ストレージ期間を持つオブジェクトがプログラムの全期間中に存在することは、標準によって保証されています。
C++ 03、3.7.1 静的保存期間 §1 :
動的保存期間もローカルでもないすべてのオブジェクトには、静的保存期間があります。これらのオブジェクトのストレージは、プログラムの期間中持続するものとします
そしてあなたの例では§4も関連しています:
static
クラス定義でクラス データ メンバーに適用されるキーワードは、データ メンバーに静的ストレージ期間を与えます。