オブジェクトの存続期間

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

オブジェクト指向プログラミング(OOP)では、オブジェクトのオブジェクトの存続期間(またはライフサイクル)は、オブジェクトの作成から破棄までの時間です。オブジェクトの有効期間のルールは、言語間、場合によっては特定の言語の実装間で大幅に異なり、特定のオブジェクトの有効期間は、プログラムの実行ごとに異なる場合があります。

場合によっては、オブジェクトの有効期間は、そのオブジェクトを値として持つ変数の変数の有効期間と一致します(静的変数自動変数の両方)が、一般に、オブジェクトの有効期間は1つの変数の有効期間に関連付けられていません。多くの場合、特に多くのオブジェクト指向言語、特にガベージコレクション(GC)を使用する言語では、オブジェクトはヒープに割り当てられ、オブジェクトの有効期間は特定の変数の有効期間(変数の値)によって決定されません。オブジェクトを保持することは、実際には参照に対応しますオブジェクト自体ではなくオブジェクトに対して、変数を破棄すると、基になるオブジェクトではなく、参照が破棄されます。

概要

オブジェクトの存続期間の基本的な考え方は単純です(オブジェクトが作成され、使用され、破棄される)が、詳細は言語間および特定の言語の実装内で大幅に異なり、メモリ管理の実装方法と密接に関係していますさらに、ステップ間、および言語レベルの概念と実装レベルの概念の間には、多くの細かい違いがあります。用語は比較的標準的ですが、特定の用語に対応するステップは言語によって大きく異なります。

用語は通常、反意語のペアで提供されます。1つは作成の概念、もう1つは初期化/ファイナライズコンストラクタ/デストラクタなどの対応する破棄の概念です。作成/破棄のペアは、他の用語の中でも、開始/終了とも呼ばれます。割り当て割り当て解除または解放という用語も、メモリ管理と同様に使用されますが、オブジェクトの作成と破棄には、単なるメモリの割り当てと割り当て解除よりもはるかに多くのことが含まれ、割り当て/割り当て解除は、それぞれ作成と破棄のステップと見なされます。

決定論

主な違いは、オブジェクトの存続期間が決定論的であるか非決定論的であるかです。これは言語によって異なり、言語内ではオブジェクトのメモリ割り当てによって異なります。オブジェクトの有効期間は、可変の有効期間とは異なる場合があります。

静的メモリが割り当てられているオブジェクト、特に静的変数に格納されているオブジェクト、およびクラスモジュール(クラスまたはモジュール自体がオブジェクトであり、静的に割り当てられている場合)は、多くの言語で微妙な非決定性を持っていますが、その存続期間は実行時間と一致しているように見えますプログラムの中で、作成と破棄の順序(どの静的オブジェクトが最初に作成され、どの静的オブジェクトが2番目に作成されるかなど)は、一般に非決定的です。[a]

自動メモリ割り当てまたは動的メモリ割り当てを使用するオブジェクトの場合、オブジェクトの作成は通常、オブジェクトが明示的に作成されたときに明示的に(newC ++やJavaなどで)、または変数の有効期間の開始時に暗黙的に、特にスコープ宣言時などに自動変数が入力されます。[b]ただし、オブジェクトの破棄はさまざまです。一部の言語、特にC ++では、スコープの終了、明示的な破棄(手動のメモリ管理による)、参照カウントなど、決定論的な時間に自動オブジェクトと動的オブジェクトが破棄されます。ゼロに達する; 一方、C#、Java、Pythonなどの他の言語では、これらのオブジェクトはガベージコレクターによっては非決定的な時間に破棄され、破棄中にオブジェクトの復活が発生して寿命が延びる可能性があります。

ガベージコレクションされた言語では、オブジェクトは通常、(スタックまたはレジスタに)自動的に割り当てられるプリミティブ値を持つ自動変数とは異なり、最初に自動変数にバインドされている場合でも、通常は動的に(ヒープ上に)割り当てられます。これにより、オブジェクトを破棄せずに関数から返すことができます(「エスケープ」)。ただし、場合によっては、コンパイラの最適化が可能です。つまり、エスケープ分析を実行し、エスケープが不可能であることを証明するため、オブジェクトをスタックに割り当てることができます。これはJavaでは重要です。この場合、オブジェクトの破棄はすぐに発生します。変数が到達できない場合は、変数の存続期間中(スコープが終了する前)でも発生する可能性があります。

複雑なケースは、オブジェクトプールの使用です。この場合、オブジェクトは事前に作成または再利用される可能性があるため、見かけの作成と破棄はオブジェクトの実際の作成と破棄に対応せず、作成とファイナライズの(再)初期化のみに対応します。破壊。この場合、作成と破棄の両方が非決定的である可能性があります。

手順

オブジェクトの作成は、メモリ割り当て初期化2つの操作に分けることができます。初期化には、オブジェクトフィールドへの値の割り当てと、場合によっては他の任意のコードの実行の両方が含まれます。これらは実装レベルの概念であり、変数の宣言定義の違いにほぼ類似していますが、後で言語レベルの違いになります。変数に関連付けられているオブジェクトの場合、宣言はメモリ割り当て(オブジェクト用のスペースの予約)にコンパイルされ、定義は初期化(値の割り当て)にコンパイルされますが、宣言はコンパイラー専用(名前解決など)の場合もあります。コンパイルされたコードに直接対応していません。

同様に、オブジェクトの破棄は、ファイナライズとメモリの割り当て解除という逆の順序で2つの操作に分けることができます。これらには、変数に関する類似の言語レベルの概念がありません。変数の有効期間は暗黙的に終了し(自動変数の場合、スタックアンワインドの場合、静的変数の場合、プログラムの終了時に)、この時点で(または後で、実装によっては)メモリの割り当てが解除されます。ただし、一般的にファイナライズは行われません。ただし、オブジェクトの有効期間が変数の有効期間に関連付けられている場合、変数の有効期間が終了すると、オブジェクトがファイナライズされます。これはC++の標準パラダイムです。

これらを合わせると、4つの実装レベルのステップが得られます。

割り当て、初期化、ファイナライズ、割り当て解除

これらのステップは、言語ランタイム、インタープリター、または仮想マシンによって自動的に実行される場合もあれば、プログラマーがサブルーチン内で、具体的にはメソッドを介して手動で指定する場合もあります。この頻度は、ステップと言語によって大幅に異なります。初期化は、クラスベースの言語ではプログラマーが指定するのが非常に一般的ですが、厳密なプロトタイプベースの言語では、初期化はコピーによって自動的に行われます。ファイナライズは、決定論的破壊を伴う言語、特にC ++でも非常に一般的ですが、ガベージコレクションされた言語ではあまり一般的ではありません。割り当てが指定されることはめったになく、通常、割り当て解除は指定できません。

作成および破棄中のステータス

重要な微妙な点は、作成または破棄のオブジェクトのステータス、および作成または破棄が失敗した場合など、エラーが発生したり例外が発生した場合の処理​​です。厳密に言えば、オブジェクトの存続期間は、割り当てが完了したときに始まり、割り当て解除が開始したときに終了します。したがって、初期化とファイナライズの間、オブジェクトは生きていますが、一貫性のある状態ではない可能性があります。クラスの不変条件が初期化の重要な部分であることを確認します。初期化が完了してからファイナライズが開始されるまでの期間は、オブジェクトが生きていて、一貫した状態になります。

作成または破棄が失敗した場合、エラー報告(多くの場合例外を発生させることによる)が複雑になる可能性があります。オブジェクトまたは関連オブジェクトが一貫性のない状態にある可能性があり、破棄の場合(通常は暗黙的に発生するため、不特定の環境で発生します)。エラーの処理が難しい場合があります。反対の問題(発信例外ではなく着信例外)は、異なる動作が必要な場合に、例外処理中に発生した場合に作成または破棄の動作を変える必要があるかどうかです。

もう1つの微妙な点は静的変数の作成と破棄が発生する場合です。静的変数の有効期間は、プログラムの実行時間と一致します。作成と破棄は、通常のプログラム実行、または通常の実行の前後の特別なフェーズで発生しますか。また、プログラムでオブジェクトがどのように破棄されるかを示します。プログラムが通常の状態または一貫した状態にない可能性がある場合の終了。これは、ガベージコレクションされた言語では特に問題になります。これは、プログラムの終了時にガベージが大量に発生する可能性があるためです。

クラスベースプログラミング

クラスベースプログラミングでは、オブジェクトの作成はインスタンス化(クラスのインスタンスの作成)とも呼ばれ作成破棄は、コンストラクタデストラクタまたはイニシャライザファイナライザと呼ばれるメソッドを介して制御できますしたがって、作成と破棄は構築破棄とも呼ばれ、これらのメソッドが呼び出されると、オブジェクトは構築または破棄された(「破棄された」ではない)と言われ、それぞれ初期化または終了されます。それらのメソッドが呼び出されたとき。

これらのメソッド間の関係は複雑になる可能性があり、言語にはコンストラクターと初期化子(Pythonなど)の両方、またはデストラクタとファイナライザー(C ++ / CLIなど)の両方が含まれる場合があります。または、「デストラクタ」と「ファイナライザー」という用語は言語を指す場合があります。レベルの構築と実装(C#とCLIの場合のように)。

主な違いは、オブジェクトが作成されるまで使用可能なオブジェクト(クラスインスタンス)がないため、コンストラクターはクラスメソッドですが、オブジェクトが作成されると、他のメソッド(デストラクタ、初期化子、およびファイナライザー)はインスタンスメソッドです。さらに、コンストラクターとイニシャライザーは引数を取ることができますが、デストラクタとファイナライザーは通常暗黙的に呼び出されるため、通常は引数を取りません。

一般的な使用法では、コンストラクタはオブジェクトを作成するためにユーザーコードによって明示的に呼び出されるメソッドですが、「デストラクタ」は、決定論的なオブジェクトの有効期間を持つ言語でのオブジェクトの破棄で呼び出されるサブルーチンです(通常は暗黙的ですが、場合によっては明示的に)。アーキタイプはC++です。 –および「ファイナライザー」は、非決定論的なオブジェクトの存続期間を持つ言語でのオブジェクトの破棄に関して、ガベージコレクターによって暗黙的に呼び出されるサブルーチンです。アーキタイプはJavaです。

ファイナライズ中の手順は、メモリ管理によって大きく異なります。手動メモリ管理(C ++や手動参照カウントなど)では、参照をプログラマーが明示的に破棄する必要があります(参照がクリアされ、参照カウントが減少します)。自動参照カウントでは、これはファイナライズ中にも発生しますが、自動化されています(Pythonの場合のように、プログラマー指定のファイナライザーが呼び出された後に発生します)。ガベージコレクションのトレースでは、これは必要ありません。したがって、自動参照カウントでは、プログラマー指定のファイナライザーが短いか存在しないことがよくありますが、ガベージコレクターのトレースではファイナライズが不要な場合がありますが、それでもかなりの作業が行われる可能性があります。

リソース管理

オブジェクトに決定論的なライフタイムがある言語では、オブジェクトのライフタイムをリソース管理のピギーバックに使用できます。これは、リソース取得は初期化(RAII)イディオムと呼ばれます。リソースは初期化中に取得され、ファイナライズ中に解放されます。特にガベージコレクションのために、オブジェクトの存続期間が非決定的である言語では、メモリの管理は通常、他のリソースの管理とは別に保持されます。

オブジェクトの作成

通常の場合、プロセスは次のとおりです。

  • オブジェクトのサイズを計算します–サイズはクラスのサイズとほとんど同じですが、異なる場合があります。問題のオブジェクトがクラスからではなくプロトタイプから派生している場合、オブジェクトのサイズは通常、スロットを保持する内部データ構造(たとえばハッシュ)のサイズになります。
  • 割り当て–可能であれば、事前に知っておくと、オブジェクトのサイズに加えて後で拡張するメモリスペースを割り当てます
  • メソッドのバインド–これは通常、オブジェクトのクラスに任されるか、ディスパッチ時に解決されますが、それでも、一部のオブジェクトモデルは作成時にメソッドをバインドする可能性があります。
  • スーパークラスの初期化コード(つまり、コンストラクター)を呼び出す
  • 作成中のクラスの初期化コードを呼び出す

これらのタスクは一度に完了することができますが、未完了のままになることがあり、タスクの順序が異なる可能性があり、いくつかの奇妙な動作を引き起こす可能性があります。たとえば、多重継承では、どの初期化コードを最初に呼び出す必要があるかは、答えるのが難しい質問です。ただし、スーパークラスコンストラクターは、サブクラスコンストラクターの前に呼び出す必要があります。

各オブジェクトを配列の要素として作成することは複雑な問題です。[さらに説明が必要]一部の言語(C ++など)はこれをプログラマーに任せています。

オブジェクトの作成中に例外を処理することは、通常、例外のスローの実装が有効なオブジェクトの状態に依存するため、特に問題があります。たとえば、メモリの空き領域が不足しているためにオブジェクトの割り当てが失敗した場合、例外オブジェクトに新しいスペースを割り当てる方法はありません。このため、オブジェクト指向言語の実装は、リソースが不足している場合でも例外を発生させるメカニズムを提供する必要があり、プログラマーまたは型システムは、コードが例外に対して安全であることを確認する必要があります。例外を伝播すると、リソースを割り当てるよりもリソースが解放される可能性が高くなります。しかし、オブジェクト指向プログラミングでは、オブジェクトを構築することでオブジェクトを確立する必要があるため、オブジェクトの構築が失敗する可能性があります。クラス不変条件。コンストラクター引数のすべての組み合わせに対して有効ではないことがよくあります。したがって、コンストラクターは例外を発生させる可能性があります。

抽象ファクトリパターンは、オブジェクトの特定の実装をコードから切り離して、そのようなオブジェクトを作成する方法です。

作成方法

オブジェクトを作成する方法は言語によって異なります。一部のクラスベース言語では、コンストラクターと呼ばれる特別なメソッドがオブジェクトの状態の検証を担当します。通常のメソッドと同様に、コンストラクターをオーバーロードして、さまざまな属性を指定してオブジェクトを作成できるようにすることができます。また、コンストラクターは不変オブジェクトの状態を設定する唯一の場所です[間違った説明が必要です]コピーコンストラクターは、コンストラクターのクラスと同じタイプの既存のオブジェクトの(単一の)パラメーターを受け取り、パラメーターとして送信されたオブジェクトのコピーを返すコンストラクターです。

Objective-Cなどの他のプログラミング言語にはクラスメソッドがあり、コンストラクタタイプのメソッドを含めることができますが、オブジェクトのインスタンス化だけに限定されません。

C ++Java[誰から?]名前付きコンストラクターを提供しない場合—コンストラクターは常にクラスと同じ名前である必要があります。これは、プログラマーが同じ引数タイプを持つ2つのコンストラクターを提供する場合、たとえば、デカルト座標または極座標のいずれかからポイントオブジェクトを作成する場合に問題になる可能性があります。どちらも、2つの浮動小数点数で表されます。Objective-Cは、プログラマーが初期化メソッド(、、、など)を使用してPointクラスを作成できるという点で、この問題を回避でき+newPointWithX:andY:ます+newPointWithR:andTheta:C ++では、静的メンバー関数を使用して同様のことができます。[1]

コンストラクターは、特に関数型言語で 、タグ付き共用体の値を作成するために使用される関数を参照することもできます。

オブジェクトの破壊

一般に、オブジェクトが使用された後、他のプログラムまたはオブジェクトがそのオブジェクトの代わりになるためのスペースを確保するために、オブジェクトがメモリから削除されます。ただし、十分なメモリがある場合、またはプログラムの実行時間が短い場合は、オブジェクトの破棄が発生せず、プロセスの終了時にメモリの割り当てが解除されるだけである可能性があります。場合によっては、オブジェクトの破棄は、特にガベージコレクションされた言語で、または「オブジェクト」が実際には単純な古いデータ構造である場合に、単にメモリの割り当てを解除することで構成されます。その他の場合、割り当てを解除する前に、特にメンバーオブジェクトを破棄する(手動メモリ管理の場合)、またはオブジェクトから他のオブジェクトへの参照を削除して参照カウントを減らす(参照カウントの場合)などの作業が実行されます。これは自動である場合もあれば、オブジェクトに対して特別な破棄メソッドが呼び出される場合もあります。

決定論的なオブジェクトの有効期間を持つクラスベースの言語、特にC ++では、デストラクタ、メモリの割り当てが解除される前に、クラスのインスタンスが削除されたときに呼び出されるメソッドです。C ++では、デストラクタはコンストラクタとはさまざまな点で異なります。オーバーロードできない、引数がない、クラスの不変条件を維持する必要がない、例外をスローするとプログラムが終了する可能性があります。

ガベージコレクション言語では、実行中のコードがオブジェクトに到達できなくなると、オブジェクトが破棄される可能性があります。クラスベースのGCed言語では、デストラクタのアナログはファイナライザあり、オブジェクトがガベージコレクションされる前に呼び出されます。ガベージコレクションは予測不可能であり、C ++デストラクタよりも大幅に使用されておらず、複雑でもないため、これらは予測できない時間と予測できない順序で実行される点で異なります。このような言語の例には、JavaPythonRubyなどがあります。

オブジェクトを破棄すると、オブジェクトへの参照が無効になり、手動のメモリ管理では、既存の参照がぶら下がっている参照になります。ガベージコレクション(ガベージコレクションのトレースと参照カウントの両方)では、オブジェクトへの参照がない場合にのみオブジェクトが破棄されますが、ファイナライズによってオブジェクトへの新しい参照が作成される場合があります。また、参照がぶら下がるのを防ぐために、オブジェクトの復活が発生し、参照が有効なままになります。

C++

クラス Foo { 
 パブリック
  //これらはコンストラクターのプロトタイプ宣言です。
Foo int x );   
  Foo int x int y ); //オーバーロードされたコンストラクタ。Foo const Foo old ); //コンストラクタをコピーします。〜Foo (); //デストラクタ。};       
      
                 


Foo :: Foo int x {  
  //これは
//1引数コンストラクターの実装です。}  


Foo :: Foo int x int y {    
  //これは
//2引数のコンストラクターの実装です。}  


Foo :: Foo const Foo old {   
  //これは
//コピーコンストラクタの実装です。}  


Foo :: 〜Foo (){ 
  //これはデストラクタの実装です。
}

int main (){  
  Foo foo 14 ); //最初のコンストラクターを呼び出します。Foo foo2 12、16 ; _ //オーバーロードされたコンストラクターを呼び出します。Foo foo3 foo ); //コピーコンストラクタを呼び出します。        
      
        

  //デストラクタは逆順で
//ここで自動的に呼び出されます。}  

Java

class  Foo 
{ 
    public  Foo int  x 
    { 
        //これは
        //1引数コンストラクターの実装です
    }

    public  Foo int  x  int  y 
    { 
        //これは
        //2引数コンストラクターの実装です
    }

    public  Foo Foo  old 
    { 
        //これは
        //コピーコンストラクターの実装です
    }

    public  static  void  main String []  args 
    { 
        Foo  foo  =  new  Foo 14 );  //最初のコンストラクターを
        呼び出しますFoofoo2 = new Foo  12、16 ; //オーバーロードされたコンストラクターを呼び出しますFoofoo3 = new Foo foo ; //コピーコンストラクターを呼び出します//ガベージコレクションは内部で行われ、オブジェクトは破棄されます} }     
             
        
    

C#

名前空間 ObjectLifeTime ;

class  Foo 
{ 
    public  Foo ()
    { 
        //これは
        //デフォルトコンストラクタの実装です。
    }

    public  Foo int  x 
    { 
        //これは
        //1引数コンストラクターの実装です。
    } 
     〜Foo (){ //これは//デストラクタの実装です}
    
        
        
    

    public  Foo int  x  int  y 
    { 
        //これは
        //2引数コンストラクターの実装です。
    }
 
    public  Foo Foo  old 
    { 
        //これは
        //コピーコンストラクターの実装です。
    }
 
    public  static  void  Main string []  args 
    { 
        var  defaultfoo  =  new  Foo ();  //デフォルトのコンストラクターを呼び出します
        varfoo =  new Foo  14 ; //最初のコンストラクター呼び出しますvarfoo2 = new Foo 12、16 ); //オーバーロードされたコンストラクターを呼び出しますvarfoo3 = new Foo foo ; //コピーコンストラクタを呼び出します} }   
              
             
    

Objective-C

#import <objc / Object.h>

@interface ポイント :オブジェクト
{
   ダブルx ; 
   ダブルy ; 
}

//これらはクラスメソッドです。2つのコンストラクターを宣言しました
+  Point * newWithX:double andY double );     
+  ポイント* newWithR:double andTheta :( double ;     

//インスタンスメソッド
-  Point * setFirstCoord:double );   
-  ポイント* setSecondCoord:double );   

/ *PointはジェネリックObjectクラスのサブクラスであるため*ジェネリック割り当てと初期化
*メソッド、+allocと-initをすでに取得しています。
特定のコンストラクターについては、
継承したこれらのメソッドから*これらを作成できます。
* /

@終わり
 
@implementation  Point

-  ポイント* setFirstCoord:double new_val    
{{
   x = new_val ;  
}

-  ポイント* setSecondCoord:double new_val    
{{
   y = new_val ;  
}

+  ポイント* newWithX:double x_val andY double y_val       
{{
   //特定の初期化を自動的に割り当てて
//実行するための簡潔に記述されたクラスメソッド。return [[[ Point alloc ] setFirstCoord x_val ] setSecondCoord y_val ]; }   
        


+  ポイント* newWithR:double r_val andTheta:double theta_val       
{{
   //上記と同じように実行する代わりに、
//前のメソッドと同じ結果を手軽に使用できますreturn [ Point newWithX r_val andY theta_val ] ;   
      
}

@終わり

int
main void 
{{
   //2つのポイントpとqを構築します。
ポイント* p = [ポイントnewWithX 4.0およびY 5.0 ];        
   ポイント* q = [ポイントnewWithR 1.0 andTheta 2.28 ];     

   // ...プログラムテキスト.... 
//pで終了しました、たとえば、それを解放します。// pがそれ自体により多くのメモリを割り当てる場合、再帰的にpのメモリを解放するために、//オブジェクトのfreeメソッドをオーバーライドする必要がある場合があります。しかし、そうではないので、[ pfree ]することができます。   
   
   
   
   
    

   //...その他のテキスト...

   [ q無料]; 

   0を返す; 
}

ObjectPascal

関連言語:「Delphi」、「Free Pascal」、「MacPascal」。

プログラム ;

タイプ

  DimensionEnum  = 
    
      deUnassigned 
      de2D 
      de3D 
      de4D 
    ;

  PointClass  =  class 
  private 
    Dimension  DimensionEnum ;

  public 
    X  整数; 
    Y  整数; 
    Z  整数; 
    T  整数;

  public 
    (*コンストラクターのプロトタイプ*)

    コンストラクター Create (); 
    コンストラクター Create AX  AY  Integer ; 
    コンストラクター Create AX  AY  AZ  Integer ; 
    コンストラクター Create AX  AY  AZ  ATime  Integer ; 
    コンストラクター CreateCopy APoint  PointClass ;

    (*デストラクタのプロトタイプ*)

    デストラクタ 破壊; 
  終了;

コンストラクター PointClass 作成(); 
begin 
  //一般的な非引数コンストラクタ
  Selfの実装ディメンション :=  deUnassigned ; 
終了;

コンストラクター PointClass 作成AX  AY  整数; 
begin 
  // a、2引数コンストラクター
  Selfの実装X  :=  AX ; 
  Y  :=  AY ;

  自己次元 :=  de2D ; 
終了;

コンストラクター PointClass 作成AX  AY  AZ  整数; 
begin 
  // a、3引数コンストラクター
  Selfの実装X  :=  AX ; 
  Y  :=  AY ; 
  自己X  :=  AZ ;

  自己寸法 :=  de3D ; 
終了;

コンストラクター PointClass Create AX  AY  AZ  ATime  Integer ; 
begin 
  // a、4引数コンストラクター
  Selfの実装X  :=  AX ; 
  Y  :=  AY ; 
  自己X  :=  AZ ; 
  T  :=  ATime ;

  自己寸法 :=  de4D ; 
終了;

コンストラクター PointClass CreateCopy APoint  PointClass ; 
begin 
  //「コピー」コンストラクタ
  APointの実装X  :=  AX ; 
  APoint Y  :=  AY ; 
  APoint X  :=  AZ ; 
  APoint T  :=  ATime ;

  自己寸法 :=  de4D ; 
終了;

デストラクタ PointClass PointClass 破壊する; 
begin 
  //一般的な非引数デストラクタ
  Selfの実装ディメンション :=  deUnAssigned ; 
終了;

var 
  (*静的割り当て用の変数*)
  S   PointClass ; 
  (*動的割り当て用の変数*)
  D  ^ PointClass ;

begin  (* of program *)
  (*静的割り当てのあるオブジェクトライフライン*)
  S 作成5、7 ; _  _

  (*「S」で何かをする*)

  S。_ 破壊する; 

  (*動的割り当てを使用したオブジェクトライフライン
  * D  =  new  PointClass  Create 5、7 ; 

  (*「D」で何かをする*)

   Dを処分し、 破壊します; 
終了  (*プログラムの*)

Python

class  Socket 
    def  __init __ self remote_host str -> None #リモートホストに接続します    
        

    def  send self ):
        #データを送信する

    def  recv self ):
        #データを受信する
        
    def  close self ):
        #ソケットを閉じます
        
    def  __del __ self ):
        #オブジェクトの参照カウントがゼロ
        selfに等しいときに呼び出される魔法の関数閉じる()

def  f ():
    socket  =  Socket "example.com" 
    socket send "test " 
    returnsocket  recv ()

ソケットへのすべての参照が失われたため、「f」関数が実行されて戻った後の次のガベージコレクションラウンドでソケットが閉じられます。

も参照してください

  • Resource Acquisition Is Initialization(RAII)は、リソースをオブジェクトの存続期間に結び付けることによってリソースを管理するためのアプローチです。

メモ

  1. ^ さまざまな微妙な点があります。たとえば、C ++では、静的ローカル変数は、関数が最初に呼び出されたときに決定論的に作成されますが、破棄は非決定論的です。
  2. ^ C ++では、静的ローカル変数の作成は、同様の方法で決定論的に行われます。実行が初めて宣言に達したときです。

参照