もちろん、以下はすべて正確ではありません。あなたがそれを読むとき、一粒の塩でそれを取ってください:)
さて、あなたが参照する 3 つのことは、自動、静的、および動的ストレージ期間です。これは、オブジェクトの存続期間と、それらが存続し始める時期と関係があります。
自動保存期間
一部のブロック内でローカルにのみ必要な、存続期間の短い小さなデータには、自動保存期間を使用します。
if(some condition) {
int a[3]; // array a has automatic storage duration
fill_it(a);
print_it(a);
}
ライフタイムは、ブロックを終了するとすぐに終了し、オブジェクトが定義されるとすぐに開始されます。それらは最も単純な種類の保存期間であり、特定の動的保存期間よりもはるかに高速です。
静的保存期間
スコープがそのような使用を許可する場合 (名前空間スコープ)、およびスコープ (ローカル スコープ) の終了後に寿命を延長する必要があるローカル変数に対して、任意のコードによって常にアクセスされる可能性がある自由変数に対して、静的ストレージ期間を使用します。クラス (クラス スコープ) のすべてのオブジェクトで共有する必要があるメンバー変数用。それらの有効期間は、それらが含まれるスコープによって異なります。名前空間スコープとローカル スコープおよびクラス スコープを持つことができます。両方について真実なのは、彼らの人生が始まると、人生はプログラムの終わりに終わるということです. 以下に 2 つの例を示します。
// static storage duration. in global namespace scope
string globalA;
int main() {
foo();
foo();
}
void foo() {
// static storage duration. in local scope
static string localA;
localA += "ab"
cout << localA;
}
はブロックの終了時に破棄されないababab
ため、プログラムは を出力します。ローカル スコープを持つオブジェクトは、制御が定義に到達したときにlocalA
有効期間が始まると言えます。の場合、関数の本体が入力されたときに発生します。名前空間スコープ内のオブジェクトの場合、有効期間はプログラムの起動時に始まります。同じことがクラス スコープの静的オブジェクトにも当てはまります。localA
class A {
static string classScopeA;
};
string A::classScopeA;
A a, b; &a.classScopeA == &b.classScopeA == &A::classScopeA;
ご覧のとおり、classScopeA
はそのクラスの特定のオブジェクトにバインドされているのではなく、クラス自体にバインドされています。上記の 3 つの名前のアドレスはすべて同じで、すべて同じオブジェクトを示します。静的オブジェクトがいつどのように初期化されるかについては特別なルールがありますが、今は気にしないでください。これは、静的初期化順序の大失敗という用語によって意味されます。
動的保存期間
最後の保存期間は動的です。オブジェクトを別の島に置きたい場合や、オブジェクトを参照するポインタを配置したい場合に使用します。また、オブジェクトが大きい場合や、実行時にしか分からないサイズの配列を作成したい場合にも使用します。この柔軟性のために、動的ストレージ期間を持つオブジェクトは複雑で、管理が遅くなります。その動的期間を持つオブジェクトは、適切なnew演算子の呼び出しが発生したときに有効期間を開始します。
int main() {
// the object that s points to has dynamic storage
// duration
string *s = new string;
// pass a pointer pointing to the object around.
// the object itself isn't touched
foo(s);
delete s;
}
void foo(string *s) {
cout << s->size();
}
その存続期間は、 deleteを呼び出したときにのみ終了します。それを忘れると、それらのオブジェクトの寿命が尽きることはありません。また、ユーザーが宣言したコンストラクタを定義するクラス オブジェクトでは、デストラクタが呼び出されません。動的な保存期間を持つオブジェクトでは、その有効期間と関連するメモリ リソースを手動で処理する必要があります。ライブラリはそれらを使いやすくするために存在します。特定のオブジェクトの明示的なガベージ コレクションは、スマート ポインターを使用して確立できます。
int main() {
shared_ptr<string> s(new string);
foo(s);
}
void foo(shared_ptr<string> s) {
cout << s->size();
}
delete の呼び出しを気にする必要はありません。オブジェクトを参照する最後のポインターがスコープ外になった場合、共有 ptr がそれを行います。共有ptr自体には、自動保存期間があります。したがって、その有効期間は自動的に管理され、デストラクタでポイントされた動的オブジェクトを削除する必要があるかどうかを確認できます。shared_ptr のリファレンスについては、boost ドキュメントを参照してください: http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/shared_ptr.htm