問題タブ [raii]
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.
c++ - boost :: shared _ ?? 非ポインタリソースの場合
基本的に、ポインタ/アドレスセマンティクスとすぐに同等ではない特定のリソース(整数インデックスなど)を参照カウントする必要があります。基本的に、リソースを回して、カウントがゼロに達したときに特定のカスタム関数を呼び出す必要があります。また、リソースへの読み取り/書き込みアクセスの方法は、単純なポインターの参照解除操作ではなく、より複雑なものです。boost :: shared_ptrがここでの法案に適合するとは思いませんが、使用する可能性のある他のBoostと同等のクラスが欠落している可能性がありますか?
私がする必要があることの例:
python - Python の RAII - スコープを離れるときの自動破棄
PythonでRAIIを見つけようとしています。Resource Allocation Is Initialization は、オブジェクトが作成時に初期化される C++ のパターンです。失敗すると、例外がスローされます。このようにして、プログラマーは、オブジェクトが半分構築された状態のままになることは決してないことを知っています。Python はこれだけのことができます。
ただし、RAII は C++ のスコープ規則とも連携して、オブジェクトの迅速な破棄を保証します。変数がスタックからポップされるとすぐに、変数は破棄されます。これは Python で発生する可能性がありますが、外部参照または循環参照がない場合に限られます。
さらに重要なことに、オブジェクトの名前は、それが含まれている関数が終了するまで (場合によってはそれよりも長く) 存在し続けます。モジュール レベルの変数は、モジュールの存続期間中保持されます。
次のようなことをすると、エラーが発生します。
使用後に名前を手動で削除することもできますが、それは非常に見苦しく、私の努力が必要です。
そして、この場合、Do-What-I-Mean を実行したいと思います。
Python はある程度の範囲指定を行いますが、インデント レベルではなく、機能レベルでのみ行います。名前を再利用できるように、変数の範囲を限定するためだけに新しい関数を作成する必要があるのはばかげているように思えます。
Python 2.5 には"with" ステートメント
がありますが、それには関数を明示的に配置する必要があり__enter__
、__exit__
通常は終了ベクトルに関係なく、ファイルやミューテックス ロックなどのリソースをクリーンアップする方向に向いているようです。スコーピングには役立ちません。または、何か不足していますか?
「Python RAII」と「Python スコープ」を検索しましたが、この問題に直接かつ正式に対処するものは見つかりませんでした。私はすべてのPEPに目を通しました。この概念は、Python 内では扱われていないようです。
Python でスコープ変数を使用したいので、私は悪い人ですか? それはあまりにも非Pythonicですか?
私はそれを理解していませんか?
おそらく、言語の動的な側面の利点を取り除こうとしているのでしょう。スコープを強制したい場合があるのは利己的ですか?
怠慢な変数の再利用の間違いをコンパイラ/インタプリタに見つけてもらいたいと思うのは怠惰ですか? そうですね、もちろん怠け者ですが、悪い意味で怠け者なのでしょうか。
c++ - オブジェクト、スコープ、RAIIの寿命を理解する
以下のコードでは、名前のないA
変数をのctorに渡すとB
、その変数は行の後に破棄されます。この答えによると:
一時オブジェクトは、それらが含まれる完全な式の最後で破棄されます。完全な式は、他の式の部分式ではない式です。通常、これは
; (or ) for if, while, switch etc.)
ステートメントの終わりを示すことで終了することを意味します。
私はそれを取得しますが、それが破壊された後、クラスはどのようB
にしてその変数の値を知ることができますか?のコピーコンストラクターがenverと呼ばれmamber_a
ていることを知っています。A
これはどのように可能ですか?
出力は次のとおりです。
c++ - longjmp と RAII
abort()
そのため、残念ながら特定のエラーを処理するために使用するライブラリ(私が作成したものではありません)があります。アプリケーション レベルでは、これらのエラーは回復可能であるため、ユーザーがクラッシュするのではなく、エラーを処理したいと考えています。したがって、次のようなコードを書くことになります。
非常にエレガントなコードではありません。このパターンはコードのいくつかの場所で繰り返さなければならないので、少し単純化し、再利用可能なオブジェクトにラップしたいと思います。私の最初の試みは、RAII を使用してシグナル ハンドラーのセットアップ/ティアダウンを処理することです (各関数で異なるエラー処理が必要なため、実行する必要があります)。だから私はこれを思いついた:
確かに の体はこの方function
がはるかに単純で明快ですが、今朝、ある考えが浮かびました。これは動作することが保証されていますか? ここに私の考えがあります:
setjmp
/の呼び出し間で揮発性または変化する変数はありませんlongjmp
。- と
longjmp
同じスタック フレーム内の場所に移動し、setjmp
通常return
は ing を実行するため、関数の終了ポイントでコンパイラが出力したクリーンアップ コードをコードが実行できるようにしています。 - 期待どおりに動作するようです。
しかし、これは未定義の動作である可能性が高いと感じています。皆さんはどう思いますか?
c++ - ivar C ++ベクトルをクリーンアップする必要があります...?
ベクトルがスタックに配置されている場合、自動変数スコープの最後で自動的に破棄されます。
クラスにベクトルを配置した場合はどうなりますか?
手動でクリーンアップする必要がありますか?もしそうなら、私はどのようにすべきですか?
c++ - C++ (または C++0x) でのヘッダー爆発の防止
次のような一般的なコードがあるとしましょう。
y.hpp:
ここで、作成したクラス (たとえば X) で Y を使用できるようにしたいと考えています。ただし、X のユーザーが Y ヘッダーを含める必要はありません。
そこで、クラス X を次のように定義します。
x.hpp:
y_ はポインターであるため、その実装を含める必要がないことに注意してください。
実装は、個別にコンパイルされた x.cpp にあります。
x.cpp:
したがって、クライアントは「y.hpp」ヘッダーをすべて含めて処理することなく、「x.hpp」を含めるだけで X を使用できます。
main.cpp:
main.cpp
これで、 とをx.cpp
別々にコンパイルできるようになり、コンパイル時main.cpp
に を含める必要がなくなりましたy.hpp
。
ただし、このコードでは生のポインターを使用する必要があり、さらに削除を使用する必要がありました。
だからここに私の質問があります:
(1) Y ヘッダーを含める必要なく、Y を X の直接メンバー (Y へのポインターではない) にする方法はありますか? (この質問に対する答えはノーだと強く思います)
(2)スマート ポインター クラスを使用して、割り当てられたヒープ Y を処理する方法はありますか? unique_ptr
当然の選択のように思えますが、行を変更するとx.hpp
から:
に:
を含め、c++0x モードでコンパイルすると、次のエラーが表示されます。
とにかく、生のポインタの代わりに標準のスマートポインタを使用し、カスタムデストラクタで生の削除を行うことでこれを行うことはありますか?
解決:
ハワード・ヒナントはそれを正しく理解しています。私たちがする必要があるのは、次のように変更することだけx.hpp
ですx.cpp
。
x.hpp:
x.cpp:
そして、unique_ptr を使用することをお勧めします。ありがとうハワード!
解決策の根拠:
私が間違っている場合は修正できますが、このコードの問題は、暗黙のデフォルトコンストラクターが Y をデフォルトで初期化しようとしていて、Y について何も知らないため、それができないことです。コンストラクターを別の場所で定義すると明示的に言うことで、コンパイラーは「Y は別の場所でコンパイルされているので、Y の作成について心配する必要はありません」と考えます。
本当に、最初にコンストラクターを追加する必要がありました。コンストラクターがないと、プログラムにバグが発生します。
c++ - デストラクタでアクティブな例外を検出する
何か問題が発生した場合のクリーンアップにRAIIを使用しているクラスがあります。これは、クラスに作業が完了したかどうかを示すフラグが含まれていることを意味します。コンストラクターが呼び出されたときにこのフラグが設定されていない場合、クラスはクリーンアップタスクを実行し、ログメッセージを生成します。今、私はこのクラスをもう一歩賢くしたいと思います。つまり、エラーが発生したのか、作業が中止されたのか(つまり、例外がスローされてデストラクタが呼び出されたのか)、または誰かがこのクラスを誤用して、決して実際に作業を終了しました。これは、例外がアクティブであるかどうかをデストラクタで確認する必要があることを意味します。見つかった場合は、ログメッセージを生成し、例外の内容を出力してから再スローする可能性があります。こんな感じだと思います。
try
ただし、デストラクタが呼び出される前に例外がすでにアクティブであり、ブロックから発生していないため、これが機能するかどうかはわかりません。また、私はthrow;
デストラクタの内部を使用しており、この時点で例外をスローすることは本当に悪い考えです。したがって、このケースがこのルール(私にはわかりません)の例外(しゃれは意図されていません)であることが標準で明確に保証されていない限り、私はそれを行いません。
それで、これはまったく可能ですか、それとも他の方法でこの状況に対処する必要がありますか?
c++ - RAII とスタックの巻き戻し
TIL RAII とスタック巻き戻しの「絡み合い」(より適切な言葉がないため) の私の概念は、(完全ではないにしても) かなり間違っています。私の理解では、RAII を使用すると、未処理の例外が原因である可能性があるものであっても、あらゆる/すべてのリソース リークを防ぐことができます。
ただし、このテスト プログラムを作成し、その後この記事/ドキュメントに出くわしたことで、スタックの巻き戻しは、たとえば、外部/その他のスコープ内の自動ではなく、try ブロック内の自動リソースに対してのみ、RAII 対応のリソースの割り当て解除が開始されることに気付きました。 .
この(新しい)理解は正しいですか?それとも、私がまだ把握していないニュアンスがありますか? そこにチャイムを鳴らしたいグルはいますか?適切な記事/分析/説明 (スタックの巻き戻しの) へのポインタは、役に立ちます/高く評価されます…</p>
c++ - ハンドル用の Win API ラッパー クラス
値によってのみ渡されるハンドルのラッパー クラスを作成するのは、比較的簡単です。アドレスで渡す必要があるハンドルをカプセル化する最善の方法を判断しようとしています。
たとえば、値によってQueryServiceConfig()に渡されるSC_HANDLEのようなもののラッパーを作成することは、それほど難しくありません。.GetHandle()のようなメンバー関数を実装するか、operator()を実装できます。
(少なくとも私にとって) 問題は、 HKEY のアドレスを必要とする RegOpenKeyEx() のようなAPI関数です。
オーバーロード演算子 & は一般的に悪い考えだと読みました。API関数へのアクセスを許可しながら、カプセル化(または可能な限り多く)、特にリソースコレクションを維持するための推奨される方法は何ですか?
c++ - 参照によるスコープガードとパラメーター
この記事の参照によるパラメーターのサポートセクションでは、問題を指摘し、参照に対する解決策を提供します。私の質問は、最初にパラメーターを参照として宣言しないのはなぜですか? つまり、代わりに:
行う: