デストラクタとは? わかりやすく解説

デストラクタ

別名:解体子
【英】destructor

デストラクタとは、C++などのオブジェクト指向プログラミング言語において、あるオブジェクト破棄する際に呼び出す関数のことである。

プログラムは処理のためにメモリ領域などの資源一時的に占有するので、処理が済んだ後はそれらの資源自由に使用できるよう開放してやる必要がある適切に開放が行なければ新しく使用できる資源少なくなってメモリリークなどの異常を起こしてしまう。デストラクタを用いればプログラム内の任意のオブジェクト終了し資源空き領域確保することができる。デストラクタにがオブジェクト開放してやることで、そのオブジェクトのために確保していた資源開放し、他のオブジェクトアプリケーションなどに資源使用できるうになる

JavaC#などの言語においてはファイナライザ(finalizer)と呼ばれる関数がデストラクタに対応している。ただし、これらのプログラミング言語では仮想マシンよばれる環境自動的に空きメモリ確保する仕組み持っているため、基本的にデストラクタを呼び出す必要はない。

ちなみに、デストラクタに対してオブジェクト初期化するための関数コンストラクタなどと呼ばれている。


参照リンク
C# および C++ のデストラクタ構文 - (Microsoft
プログラミングのほかの用語一覧
オブジェクト指向:  COM  多重継承  単一継承  デストラクタ  UML
コーディング:  ActiveRecord  アキュムレーター

デストラクタ

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/01/07 17:57 UTC 版)

デストラクタ: destructor)は、オブジェクト指向プログラミング言語でオブジェクト(インスタンス)を削除する際に呼び出されて後処理などを行なう関数あるいはメソッドのこと。C++DelphiRustにおいてサポートされている。デストラクタは確実かつ安全なリソース管理を実現するための重要な役割を担う。

日本語では「解体子」という直訳が割り当てられることもあるが[1]、ほとんど使用されることはない。

なお、本項では類似概念であるファイナライザについても合わせて述べる。

C++

デストラクタはオブジェクトの寿命が終了するタイミング、メモリ領域が破棄される直前に自動的に呼び出される。具体的には自動変数(ローカル変数)ならばその変数が属するブロックを抜けた直後、静的オブジェクトならばプログラム終了直前、new演算子で生成したオブジェクトならばdelete演算子が適用された時である。主にコンストラクタで確保したリソースを解放するための処理が記述される。

派生クラスの場合は、まず派生クラスのデストラクタが呼ばれて派生クラスによる追加部分が解体されてから、基底クラスのデストラクタが順次呼ばれることでオブジェクトが解体される。基底クラスのポインタで派生クラスのインスタンスをポリモーフィックに利用する場合は、基底クラスのデストラクタを仮想関数にしなければならない(仮想デストラクタ)。これはポインタが参照するインスタンスをdeleteする際に呼び出されるデストラクタがポインタの型で決定されるため、基底クラスのデストラクタが仮想でない場合は、基底クラスのデストラクタだけが呼ばれて派生クラスのデストラクタが呼ばれないためである。基底クラスが仮想デストラクタを持っていれば、実際のインスタンスに応じて派生クラスのデストラクタが正しく呼び出される。ただしこのメカニズムは一般的な仮想関数と同様に仮想関数テーブルを経由して実現されるものであるため、デストラクタを仮想にするとオブジェクトのメモリ上のサイズが多少増加し、また仮想関数テーブルを経由することで呼び出しのオーバーヘッドが多少増えることになる。

自動変数のデストラクタは、例外でブロックを脱出した際にも呼び出される。そのため、コンストラクタでリソースを確保し、デストラクタでリソースを解放するクラスを自動変数として生成することで、ブロック中のどこから例外が投げられてもリソースの解放が確実に行われる。このイディオムをRAII (Resource Acquisition Is Initialization) という。

デストラクタは例外を投げるべきではない。先に述べたようにデストラクタは例外伝播中にも呼ばれる可能性があるが、その時にデストラクタがさらに例外を投げると二重例外となり、プログラムの強制終了を招くからである。

デストラクタは、プログラマが定義しない場合にC++コンパイラが暗黙に生成するメンバー関数のうちの一つである。暗黙のデストラクタの仕様は「中身が空」で「非仮想」となっている。

デストラクタの名前は、クラス名の前に~記号(チルダ、ティルダ)を付けたものと決められている。

下記の例では、main関数を抜けるときにMyClass型の自動変数objが破棄されることによって、デストラクタ~MyClass()が自動的に呼ばれる。

#include <iostream>

class MyClass {
public:
    // デフォルトコンストラクタ。
    MyClass() { std::cout << "MyClass() is called." << std::endl; }
    // デストラクタ。
    ~MyClass() { std::cout << "~MyClass() is called." << std::endl; }
};

int main() {
    std::cout << "main() function started." << std::endl;
    MyClass obj; // 関数ブロックを抜けると破棄される。
    std::cout << "main() function finished." << std::endl;
}

例えばnew演算子で動的に生成した別のオブジェクト(動的に確保したメモリ領域)へのポインタや、オープンしたファイルのハンドルなどをクラスのメンバー変数として保持しておき、delete演算子による削除(メモリ領域の解放)やファイルのクローズといった後始末用の処理をデストラクタに記述することで、クラスオブジェクトの寿命が尽きたときに後始末を確実に自動実行させることができる。

ファイナライザ

ファイナライザ (finalizer) は、ガベージコレクタを持つ言語において不要オブジェクトが回収される前に自動的に呼び出されるメソッドである。

JavaRubyなどに存在する。C++/CLIにはデストラクタとファイナライザの両方が存在する。C#にはファイナライザのみが存在するが、構文がC++のデストラクタに酷似しており、かつては「デストラクタ」と呼ばれていた[2][3]

デストラクタと違い、ファイナライザはオブジェクトが不要になってもすぐには呼ばれるとは限らない。不要になってから実際に回収されるまでの間に、いつか呼ばれるというだけである。それは不要になった直後かもしれないし、遙か後になるかもしれない。さらにはメモリに十分な余裕があれば、オブジェクトが回収されずファイナライザが永遠に呼ばれないということさえありうる。.NET Frameworkの場合はアプリケーションの終了時にファイナライザが呼ばれるが、一般的にはプロセス終了時ですらファイナライザが呼ばれるかどうかは不定である。

このようにいつ呼び出されるかわからない、呼ばれるかどうかすらわからないメソッドのため、確実に実行されなければならないような処理は一般的にファイナライザに任せることはできない。したがって、「ファイナライザによるRAII」は誤りである。ファイナライザで行えることは極めて限定されており、「リソースを解放し忘れていないか確認し、解放し忘れていれば解放する」というような最終防壁としての利用法がせいぜいである。リソースは不要になった時点で適切に解放されているべきであり、ファイナライザのチェックは保険に過ぎない。解放し忘れは本来はバグで、ファイナライザに頼る設計をしてはいけない。ファイナライザを誤って実装すると、脆弱性が生じることもある[4]

以上のような不確実性に加え、ファイナライザの利用はガベージコレクタの性能を低下させることもあり、積極的に利用されるものではない。ファイナライザを持つオブジェクトはファイナライザ管理リストに登録されるため、ファイナライザを持たないオブジェクトと比べてオーバーヘッドも増える[5]。業務サーバーのような、少々のバグがあっても動き続けていなければ困るようなアプリケーションでは用いられることもある。

Java 9ではファイナライザが非推奨となった[6]

他言語の類似機能

「デストラクタによるRAII」に近い機能を実現する手段は、JavaではAutoCloseableインターフェイスの実装とtry-with-resources文、C#ではSystem.IDisposableインターフェイスの実装とusing文である。なお、C++/CLIでは、マネージ型にデストラクタを定義するだけでIDisposableインターフェイスを暗黙的に実装したことになる[7]

Objective-Cでは、インスタンスの参照カウントがゼロになったときにdeallocメソッドがランタイムによって自動的に呼ばれる[8]。このメソッド内に各種の後始末処理(Objective-Cの管理下にないリソースの解放など)を記述することができる。Swiftでの該当機能はデイニシャライザdeinitである[9]

脚注

関連項目


デストラクタ




固有名詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「デストラクタ」の関連用語

デストラクタのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



デストラクタのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
PHPプロ!PHPプロ!
©COPYRIGHT ASIAL CORPORATION ALL RIGHTS RESERVED.
IT用語辞典バイナリIT用語辞典バイナリ
Copyright © 2005-2024 Weblio 辞書 IT用語辞典バイナリさくいん。 この記事は、IT用語辞典バイナリの【デストラクタ】の記事を利用しております。
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのデストラクタ (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。
Text is available under Creative Commons Attribution-ShareAlike (CC-BY-SA) and/or GNU Free Documentation License (GFDL).
Weblioに掲載されている「Wiktionary日本語版(日本語カテゴリ)」の記事は、Wiktionaryのデストラクタ (改訂履歴)の記事を複製、再配布したものにあたり、Creative Commons Attribution-ShareAlike (CC-BY-SA)もしくはGNU Free Documentation Licenseというライセンスの下で提供されています。

©2024 GRAS Group, Inc.RSS