質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

3216閲覧

デストラクタの呼び出しはどのタイミングですか?

King_of_Flies

総合スコア382

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/10/25 03:04

お疲れ様です。

現在、デストラクタについて調べています。
デストラクタの逆関数であるコンストラクタは、
オブジェクトが生成されたときに呼び出されるということで、
コードで例えるならばNewされた時とわかりやすいのですが、
デストラクタのオブジェクトが破棄されたとき(解放されたとき)というのは、
コードで例えるとどのような処理に当てはまりますか。

Closeで良いのでしょうか?
VBAでは、下記コードでコンストラクタは呼び出せます。
Dim M As New MyClass ← オブジェクトの生成。コンストラクタが呼び出される。

オブジェクトの破棄は調べると下記文言がありましたが、
明示的な破棄は一般的にされないのでしょうか?

■オブジェクトが破棄されるタイミング

 参照カウント方式です。オブジェクトへの参照数が0になると、すぐに破棄されます。
そのとき、Terminateイベントが呼び出されます(※1)。

ここでいう参照カウント方式では、下記URLを参考に調べました。

https://ja.wikipedia.org/wiki/%E5%8F%82%E7%85%A7%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88

すべてのオブジェクト(メモリ上におかれているデータの単位)に対して、参照カウントと呼ばれる整数値を付加しておく。これは、このオブジェクトへのポインタがシステム全体にいくつ存在しているかを数えるものである。

上記が参照カウント方式でのカウント方式らしいのですが、
>このオブジェクトへのポインタがシステム全体にいくつ存在しているかを数えるものである。
この部分の理解がいまいちです。

たとえば下記コードがあったとして、Mのオブジェクトのカウントは6ということでしょうか?

vba

1Sub Test() 2 Dim M As New MyClass 3 M.method1() 4 M.method2() 5 M.method3() 6 M.method4() 7 M.method5() 8End Sub

6つ最初にカウントしておいて、Mの使用がされるたびに減算していく方式?ということであっていますか?

つまり、M.method5()の実行後、カウントが0になり、デストラクタが呼び出されるということで良いですか?

デバッグで確認すると、デストラクタの呼び出しは、
Test()のEnd Sub通過後になっているようなので、
どういう方式で減算されていっているのか不明です。

お願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

たとえば下記コードがあったとして、Mのオブジェクトのカウントは6ということでしょうか?

VBA

1Sub Test() 2 Dim M As New MyClass 3 M.method1 4 M.method2 5 M.method3 6 M.method4 7 M.method5 8End Sub

いいえ。Method1~5は単にMオブジェクト内の話なので、Mオブジェクトの参照としては1です。

■オブジェクトが破棄されるタイミング
参照カウント方式です。オブジェクトへの参照数が0になると、すぐに破棄されます。

MオブジェクトはTest()のスコープ内でインスタンスが生成されているので、
Test()が終了するとスコープでの参照が無くなる為、破棄されます。

スコープ内で明示的に破棄する場合はNothingを使用します。

VBA

1Sub Test() 2 Dim M As New MyClass 3 M.method1 4 M.method2 5 M.method3 6 M.method4 7 M.method5 8 9 M = Nothing 10End Sub 11 12

投稿2017/10/25 04:22

sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BeatStar

2017/10/25 04:26

ああ、Nothingがありましたね。 JavaScriptでも obj = null; ってやっていたりするし。
guest

0

ベストアンサー

私は趣味でC++ ( Better-C )やっています。

VBAはあまり使っていませんが。

たぶん、そのページの「カウンタ方式である」云々は動かした回数ではなく、

ブロックごとに生成された回数 だと思います。

実際、C++には ガーベージコレクタ ( GC ) はないので、プログラマ自身がdelete ( 破棄 ) する必要がありますが、

C++11っていう比較的新しいバージョンではスマートポインタ と呼ばれるクラス? が用意されています。

その前までは auto_ptr っていうものがあったらしいですが、これは色々エラーを引き起こすようで、代わりとなる shared_ptr, weak_ptr 等が考案されたようです。

で、shared_ptrは カウンタ方式らしいです。

これはブロックごとに計算するようです。

VBA風に書くと、

VBA

1Sub test1() 2 ' Class1 というクラスがあるとして 3 Dim obj As Class1 4 Set obj = New Class1 5 test2 obj 6End Sub 7 8Sub test2( ByVal obj As Class1 ) 9 obj.text = "hello" 10 ' 何らかの処理 11 test3 obj 12End Sub 13 14Sub test3( ByVal obj As Class1 ) 15 MsgBox obj.text 16End Sub

としたら、

test1 内で objが生成されています。その後 test2に渡されて処理。test2はtest3にobjを渡して処理...となっています。

このとき、test2 ~ test3 の間でdeleteされたらどうなるでしょう。

ヌルポ状態になるので、存在しないオブジェクト で動かそうとしているのでクラッシュします。

クラッシュしなくても想定外のことがおきる可能性が高い。

なので、「あ、これ以上使われないだろうな」と推測される場合にdeleteされるのでは?

つまり、上記の例だと、

test1 で カウンタ + 1,
test2 で カウンタ + 1 = 2,
test3 で カウンタ + 1 = 3

test3 のブロック終了 ( 例だと End Sub ) で カウンタ - 1 = 2,
test2 のブロック終了 ( 例だと End Sub ) で カウンタ - 1 = 1,
test1 のブロック終了 ( 例だと End Sub ) で カウンタ - 1 = 0

0 だと誰もアクセスしようとしないだろうから破棄。

っていう。

ということで、カウンタ方式っていうのはブロック開始で+1し、ブロックを抜けるとき( 抜けた後? ) に -1 し、そのカウンタが0になったら誰もアクセスしないということ なので C++で言えば delete, Java等のGCがある言語だとGCが呼ばれるっていうことだと思います。

投稿2017/10/25 03:25

編集2017/10/25 03:29
BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

King_of_Flies

2017/10/25 04:05

わかりやすかったです。 回答ありがとうございます。
BeatStar

2017/10/25 04:35

Saziさんの回答にある "Nothing" で明示的にdeleteすれば ブロックを抜けていなくても カウンタが -1されて、0のときにデストラクタが呼ばれる...っていう状態かも。 ( 試していないので詳しくはわかりませんが。 )
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問