問題タブ [destructor]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
11 に答える
547 参照

c# - 必要な関数呼び出しの強制

次のように使用される C# の「ステータス」クラスがあります。

あなたはアイデアを得る。MyFunction のすべての呼び出し元は、返された Status を確認する必要があります。

ただし、怠惰な呼び出し元はステータスを無視できます。

また

これを不可能にすることは可能ですか?例外のスローなど

一般に、特定の関数を呼び出さなければならない C# クラスを作成することは可能ですか?

C++ バージョンの Status クラスでは、デストラクタでプライベート bool bIsChecked に対するテストを記述し、誰かがこのインスタンスをチェックしない場合にベルを鳴らすことができます。

C# の同等のオプションは何ですか? 「C#クラスにデストラクタは必要ない」とどこかで読みました

IDisposable インターフェイスの Dispose メソッドはオプションですか?

この場合、解放するアンマネージ リソースはありません。さらに、GC がいつオブジェクトを破棄するかは決定されません。最終的に破棄されたときに、その特定の Status インスタンスをいつどこで無視したかを知ることは可能ですか? 「using」キーワードは役に立ちますが、怠惰な呼び出し元には必要ありません。

0 投票する
5 に答える
86181 参照

c++ - C++では、コンストラクタとデストラクタをインライン関数にすることができますか?

VC++ は、クラス宣言内で実装される関数をインライン関数にします。

次のようにクラスを宣言するFooと、CONSTRUCTOR および DESTRUCTOR インライン関数になりますか?

0 投票する
4 に答える
11719 参照

vb.net - VB.NET - IDisposable を実装するときに Finalize メソッドを追加する必要がありますか?

Visual Studio で " Implements IDisposable" という行を入力すると、IDE によって次のものが自動的に追加されます。

  • メンバーdisposedValue変数
  • aSub Dispose() Implements IDisposable.Dispose
  • aSub Dispose(ByVal disposing As Boolean)

はそのDispose()ままにして、クリーンアップ コードを に配置する必要がありますDispose(disposing)

ただし、Dispose Finalize パターンSub Finalize()は、 callをオーバーライドする必要があることも示していますDispose(False)。なぜIDEもこれを追加しないのですか? 自分で追加する必要がありますか、それとも何らかの方法で暗黙的に呼び出されますか?

編集: IDE が必要なものの 80% を自動的に追加するのに、Finalize メソッドを省略している理由がわかりませんか? この種の機能の要点は、これらのことを忘れないようにすることではないでしょうか?

EDIT2:素晴らしい回答をありがとうございました。これは完全に理にかなっています!

0 投票する
3 に答える
341 参照

c++ - 例外が発生しているかどうかを判断する方法はありますか?

デストラクタで、例外が現在処理されているかどうかを判断する方法はありますか?

0 投票する
17 に答える
131377 参照

c++ - デストラクタで例外をスローしてはならない場合、デストラクタでエラーをどのように処理しますか?

ほとんどの人は、デストラクタから例外をスローしないと言っています。そうすると、未定義の動作が発生します。Stroustrup は、「ベクトル デストラクタはすべての要素に対して明示的にデストラクタを呼び出すことを強調しています。これは、要素デストラクタがスローした場合、ベクトルの破壊が失敗することを意味します...デストラクタからスローされた例外から保護する良い方法は実際にはありません。そのため、ライブラリは要素デストラクタがスローするかどうかは保証しません」(付録 E3.2 より)

この記事では、デストラクタのスローは多かれ少なかれ問題ないと言っているようです。

だから私の質問はこれです - デストラクタからスローすると未定義の動作になる場合、デストラクタ中に発生したエラーをどのように処理しますか?

クリーンアップ操作中にエラーが発生した場合、それを無視しますか? スタックで処理できる可能性があるが、デストラクタで正しく処理できないエラーである場合、デストラクタから例外をスローするのは理にかなっていませんか?

明らかに、この種のエラーはまれですが、発生する可能性があります。

0 投票する
8 に答える
8448 参照

c++ - RAIIと例外

C ++でRAIIを使用すればするほど、重要な割り当て解除を行うデストラクタを使用するようになります。現在、割り当て解除(ファイナライズ、ただし、それを呼び出したい場合)は失敗する可能性があります。その場合、例外は、実際には、2階の誰かに割り当て解除の問題を知らせる唯一の方法です。ただし、スタックの巻き戻し中に例外がスローされる可能性があるため、スローデストラクタはお勧めできません。std::uncaught_exception()それがいつ発生するかを知らせますが、それ以上ではありません。したがって、終了前にメッセージをログに記録できるようにする以外に、プログラムを未定義の状態のままにしておく場合を除いて、できることはほとんどありません。とそうでないものもあります。

1つのアプローチは、スローしないデストラクタを使用することです。しかし、多くの場合、それは実際のエラーを隠すだけです。たとえば、デストラクタは、いくつかの例外がスローされた結果として、一部のRAII管理のDB接続を閉じている可能性があり、それらのDB接続は閉じられない可能性があります。これは、プログラムがこの時点で終了しても問題がないことを必ずしも意味するものではありません。一方、これらのエラーをログに記録して追跡することは、実際にはすべての場合の解決策ではありません。そうでなければ、そもそも例外は必要ありませんでした。スローしないデストラクタを使用すると、破棄前に呼び出されるはずの「reset()」関数を作成する必要がありますが、これはRAIIの目的全体を損なうだけです。

もう1つのアプローチは、プログラムを終了させることです。これは、実行できる最も予測可能なことです。

一度に複数のエラーを処理できるように、例外を連鎖させることを提案する人もいます。しかし、正直なところ、C ++で行われることを実際に見たことがなく、そのようなことを実装する方法がわかりません。

つまり、RAIIまたは例外のいずれかです。ではない?私はスローしないデストラクタに傾いています。主にそれが物事を単純に保つからです(r)。しかし、私が言ったように、RAIIを使用すればするほど、重要なことを行うdtorを使用するようになるので、より良い解決策があることを本当に望んでいます。

付録

私が見つけた興味深い話題の記事やディスカッションへのリンクを追加しています:

0 投票する
25 に答える
636818 参照

java - Javaのデストラクタはありますか?

Javaのデストラクタはありますか? これに関するドキュメントを見つけることができないようです。そうでない場合、どうすれば同じ効果を得ることができますか?

質問をより具体的にするために、データを処理するアプリケーションを作成しています。仕様では、アプリケーションを起動したばかりの元の状態に戻す「リセット」ボタンが必要であると書かれています。ただし、アプリケーションを閉じるかリセット ボタンを押さない限り、すべてのデータは「ライブ」である必要があります。

普段は C/C++ プログラマーなので、これを実装するのは簡単だと思いました。(したがって、最後に実装する予定でした。)リセットボタンが押されたときにすべての「ライブ」オブジェクトを破棄できるように、すべての「リセット可能な」オブジェクトが同じクラスになるようにプログラムを構成しました。

データを逆参照してガベージ コレクターがデータを収集するのを待つだけだとしたら、ユーザーが繰り返しデータを入力してリセット ボタンを押すと、メモリ リークが発生しないのではないかと考えていました。また、Java は言語として非常に成熟しているため、これが起こらないようにするか、適切に対処する方法があるはずだと考えていました。

0 投票する
7 に答える
8685 参照

.net - .NET に RAII がないのはなぜですか?

主に C++ の開発者である私は、Java と .NET にRAII (Resource Acquisition Is Initialization)がないことにいつも悩まされてきました。クリーンアップの責任がクラスの作成者から消費者に移されたという事実 (try finallyまたは .NET のusingコンストラクトによって) は、著しく劣っているように思われます。

すべてのオブジェクトがヒープ上にあり、ガベージ コレクターが本質的に決定論的破壊をサポートしていないため、Java で RAII がサポートされていない理由がわかりましたが、値型 ( struct) の導入により .NET では (一見) RAIIの完璧な候補。スタック上に作成された値型には明確に定義されたスコープがあり、C++ デストラクター セマンティクスを使用できます。ただし、CLR では、値型がデストラクタを持つことは許可されていません。

私のランダムな検索では、値の型がボックス化されている場合、ガベージ コレクターの管轄下にあるため、その破棄が非決定的になるという 1 つの引数が見つかりました。この議論は十分に強力ではないと感じています。RAII の利点は、デストラクタを持つ値型をボックス化 (またはクラス メンバーとして使用) できないと言うのに十分大きいです。

簡単に言うと、私の質問は次のとおりです。RAII を .NET に導入するために値型を使用できない理由は他にありますか? (または、RAII の明らかな利点についての私の議論には誤りがあると思いますか?)

編集:最初の4つの回答が要点を逃したため、質問を明確に表現していなかったに違いありません。私はその非決定論的特性について知っており、構造について知っており、これら2つのオプションは RAII よりも劣っていると感じています。は、クラスの消費者が覚えておかなければならないもう 1 つのことです (ブロックに aを入れるのを忘れた人は何人いますか?)。私の質問は、言語設計に関する哲学的なものです。なぜそうなのか、改善できるのでしょうか?FinalizeusingusingStreamReaderusing

たとえば、一般的な決定論的に破壊可能な値型を使用すると、usingandlockキーワードを冗長にすることができます (ライブラリ クラスによって達成可能)。


私は、かつて見たが、現在その出所を見つけることができない適切な引用で終わらせざるを得ません。

私の冷たい死んだ手が範囲外になると、私の決定論的破壊を受け取ることができます. --アノン

0 投票する
8 に答える
12871 参照

c# - コンストラクターが例外をスローした場合、デストラクタは呼び出されますか?

C# および C++ の回答を探しています。(C# では、「デストラクタ」を「ファイナライザ」に置き換えます)

0 投票する
4 に答える
1948 参照

ruby - Ruby の RAII (または、Ruby でリソースを管理する方法)

オブジェクトが破壊されたときに何が起こるかを制御できないのは設計上のものであることはわかっています。また、一部のクラス メソッドをファイナライザーとして定義することも認識しています。

しかし、C++ の RAII (リソースはコンストラクタで初期化され、デストラクタで閉じられる) の Ruby イディオムですか? エラーや例外が発生した場合でも、オブジェクト内で使用されるリソースをどのように管理しますか?

確実に動作するようにする:

ただし、クラスのユーザーは、open メソッドを呼び出す必要があるたびに、 begin-rescue-ensure チャチャ全体を実行することを覚えておく必要があります。

たとえば、次のクラスがあります。

例外が他のクラスによって引き起こされ、スクリプトが終了した場合、resource_handle は閉じられません。

それとも、私がまだこれをC++のようにやっているという問題ですか?