FreeBASIC マニュアルのトップに戻る

FreeBASIC ProPgCtorsDtors

目次→教本→プログラマーのための案内Constructors and Destructors←オリジナル・サイト

構築子と解体子(基本) 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

オブジェクトの作成と破壊を、担当します。

概要
宣言
デフォルト構築子
コピー構築子
構築子を呼ぶ
コンパイラで提供される構築子と解体子

概要
構築子と解体子は、それぞれオブジェクトを作成して、破壊するのに、関与します。
一般に、構築子は、オブジェクトに、その初期状態を与えます。すなわち、構築子は、オブジェクトの構成データに、その重要な値を与えます。
解体子は、反対の機能を実行します。
解体子は、オブジェクトによって所有されていたリソースを、適切に解放するのを確実にします。

簡単に言うと、構築子はオブジェクトの作成時に呼び出される特別なメンバ手続きで、解体子はオブジェクトの破棄時に呼び出される特別なメンバ手続きです。
Dim または New Expression/Delete Statement キーワードを使用して明示的に、または、オブジェクトを手続きに値渡しすることによって、あるいはオブジェクトがスコープ外に出ることによって、黙示的に、オブジェクトが作成されまたは破棄されるたびに、構築子と解体子の両方が、コンパイラによって自動的に呼び出されます。

宣言
構築子と解体子は、メンバー手続きにもかかわらず、SubFunction の代わりに、Constructor キーワードで、名前なしで宣言されます。
同様に、構築子と解体子は、宣言の中で、TypeClass という名前だけで定義されます。

TypeClass は、複数の構築子を持ちますが、解体子は、一つしか持つことができません。

デフォルト構築子
デフォルト構築子は、パラメータを持たないか、またはすべてのパラメータにデフォルト値がある構築子です。
デフォルト構築子は、オブジェクトが定義されているが初期化されていないとき、または Dim, Redim, New[] 式のいずれかのキーワードで、配列の一部として作成されたときに、呼び出されます。
以下の例で宣言されている最初の構築子は、デフォルト構築子です。

構築子をコピー
コピー構築子は、オブジェクトが作られるか、または、同じ型(または、その型に変換できるオブジェクト)の別のオブジェクトから、クローンを作られるとき呼ばれる、構築子です。
これは、オブジェクトを、他のオブジェクトで初期化するとき、明示的に発生します。あるいは、オブジェクトを、手続きに、値で渡すときに、黙示的に発生します。
コピー構築子は、1つのパラメタを持って、宣言されます:
同じ型のオブジェクトは、参照で渡されます。

コピー構築子は、オブジェク・トインスタンスを作成・初期化するときだけ、呼ばれます。
オブジェクトへの代入は、member operator let で扱われます。

構築子を呼ぶ
他のメンバ手続きとは異なり、構築子は通常、オブジェクト・インスタンスから直接呼び出されません。
代わりに、構築子は、初期化子の有無にかかわらず Dim 命令文で指定するか、引数の有無にかかわらず New Expression 命令文で指定します。

オブジェクトに初期化子を指定するとき、初期化子が要求する引数の後ろに続く型の名前が、使われます。

Type foo
    '' default ctor, copy ctor と normal ctor を宣言します
    Declare Constructor
    Declare Constructor (ByRef As foo)
    Declare Constructor (As Integer)

    '' 解体子を宣言します
    Declare Destructor

    ints As Integer Ptr
    numints As Integer
End Type

'' 100の整数を生成する構築子を定義します
Constructor foo
    ints = New Integer (100)
    numints = 100
End Constructor

'' 整数を、別のオブジェクトからコピーする構築子を定義します
Constructor foo (ByRef x As foo)
    ints = New Integer (x.numints)
    numints = x.numints
End Constructor

'' いくつかの整数を、パラメタに基づき作成する構築子を、定義します
Constructor foo (n As Integer)
    ints = New Integer (n)
    numints = n
End Constructor

'' これらの整数を破壊する解体子を定義します
Destructor foo
    Delete[] ints
End Destructor

Scope
    '' foo の default ctor を呼びます」
    Dim a As foo
    Dim x As foo Ptr = New foo

    '' foo の copy ctor を呼びます
    Dim b As foo = a
    Dim y As foo Ptr = New foo (*x)

    '' foo の normal ctor を呼びます
    Dim c As foo = foo (20)
    Dim z As foo Ptr = New foo (20)

    '' foo の dtor を呼びます
    Delete x
    Delete y
    Delete z
End Scope '' <- a、b、c は、ここで破壊されます



コンパイラで提供される構築子と解体子
TypeClass で、何もコピー構築子を宣言していないと、コンパイラはコピー構築子を提供します。
構築子が宣言されていない場合も、コンパイラはデフォルト構築子を提供します。

コンパイラーで提供されるデフォルト構築子は、メンバー・データをデフォルト値に初期化します。 すなわち、数値とポインター・メンバーは、ゼロ (0) に設定されます。また、オブジェクト・メンバーはデフォルトで構築されます。
コンパイラーが宣言するコピー構築子は、全てのメンバー・データを、一つの型から、別のものに、浅い(shallow)コピーをします:
浅い(shallow)コピーでは、数値とポインター型は、コピーされるオブジェクトの対応するデータ・メンバーで、初期化されます。
そして、オブジェクト・メンバーは、それらの対応するオブジェクト・メンバーからコピー構築されます。
これは、ポインタ・データ・メンバーによって指されたメモリのような、動的な資源は、コピーされないことを意味します; アドレスだけがコピーされます。
したがって、オブジェクトが資源を所有していれば、その生成と破壊の原因になることを意味します。このため、コンパイラーが生成したコピー構築子では、不十分です。


解体子が宣言されていないと、コンパイラは解体子を生成します。
この解体子は、オブジェクト・メンバーの解体子を呼びます。数値とポインター型のためには、何もしません。
一方、オブジェクトが動的資源を所有していると、コンパイラが生成した解体子では不十分です。オブジェクトが破壊されるとき、資源は解放されません。

これは一般に「3つの規則」と呼ばれます:
オブジェクトで、カスタムコピー構築子、代入演算子、解体子のいずれかを必要とする場合、オブジェクトは、これら 3つ全てを必要とします。


参照
プログラマーのための案内に戻る
←リンク元に戻る プログラム開発関連に戻る

ページ歴史:2019-09-05 02:58:34
日本語翻訳:WATANABE Makoto、原文著作者:LaananFisher

ホームページのトップに戻る

表示-非営利-継承