第 3 章「例外およびエラー処理」を完了、抜粋
コンストラクターと例外
このトピックは C++ コミュニティではよく言及されますが、Delphi コミュニティでは誰も注目していないようです。おそらく言語の特性のため、Delphi プログラマはこの問題を心配する必要はありません。しかし、Delphi プログラマーもこの問題を理解し、この問題を簡単に無視できるように言語が提供するものを理解する必要があると思います。ことわざにあるように、「祝福に囲まれているときは、その祝福を知らなければなりません」。クラスのコンストラクターには戻り値がないことがわかっています。コンストラクターがオブジェクトの構築に失敗した場合、エラー コードを返すことに頼ることはできません。では、プログラム内のコンストラクターの失敗をどのように特定するのでしょうか?最も「標準的な」方法は、例外をスローすることです。コンストラクターの失敗は、オブジェクトの構築が失敗することを意味します。では、例外がスローされた後、この「半分死んだ」オブジェクトはどのように処理されるのでしょうか。ここでは、C++ がこの状況をどのように処理するかを理解した上で読む必要があると思います。 C++ では、コンストラクターが例外をスローした後はデストラクターは呼び出されません。現時点ではオブジェクトが完全には構築されていないため、このアプローチは合理的です。コンストラクターがメモリの割り当て、ファイルのオープンなどの操作を実行した場合、C++ クラスは、実行されたアクションを記憶するために独自のメンバーを持つ必要があります。もちろん、これはクラスの実装者にとって非常に面倒なため、一般に C++ クラスの実装者はコンストラクターで例外をスローすることを避けます (Init や UnInit などのメンバー関数を提供できますが、これはコンストラクターまたはクラス クライアントに呼び出されて処理されます)。初期化失敗)。すべての古典的な C++ 書籍で提供されている解決策は、スマート ポインター (STL の標準クラス auto_ptr) を使用することです。 Object Pascal では、この問題は非常に単純になり、プログラマは心配する必要がなくなります。 Object Pascal クラスがコンストラクターで例外をスローした場合、コンパイラーは自動的にクラスのデストラクターを呼び出します (デストラクターはオーバーロードが許可されていないため、デストラクターは 1 つだけであることが保証され、コンパイラーが混乱することはありません) .複数のデストラクターの間)。メンバー オブジェクトは通常、デストラクター内で破棄されます。Free() メソッドは、デストラクターが nil オブジェクト (つまり、まだ作成されていないメンバー オブジェクト) に対して呼び出されないようにするため、コードを簡潔かつ美しくします。安全性も確保します。 type MyClass = classPRivateFStr : PChar; // 文字列ポインタ publicconstructor Create();destructor Destroy(); override;end;constructor MyClass.Create();beginFStr := StrAlloc(10); // コンストラクタ内の文字列ポインタ AllocatememoryStrCopy( FStr, 'ABCDEFGHI');raise Exception.Create('error'); //例外をスローします、理由はありません hahaend;destructor A.Destroy();beginStrDispose(FStr); // デストラクター内のメモリを解放します WriteLn('Free Resource');end;varObj : TMyClass;i : integer;begintryObj : = TMyClass.Create ();Obj.Free();WriteLn('成功');Obj を除く := nil;WriteLn('Failed');end;Read(i); // 実行結果を確認するために画面を一時停止します。このコードでは、コンストラクターが例外をスローし、実行結果は次のようになります。「Free ResourceFailed」 Free Resource」出力は、デストラクターを自動的に呼び出すコンパイラーによって生成されます。したがって、クラスのドキュメントまたはクラスの作成者から、クラス コンストラクターが例外をスローする可能性があることが示されている場合は、それを try...excel でラップすることを忘れないでください。 C++ と Object Pascal がコンストラクターによってスローされた例外を処理するさまざまな方法は、実際には 2 つの言語の設計思想を具体化したものです。 C++ は C のスタイルに準拠しており、すべてがプログラマに委ねられており、コンパイラは不必要な動作を行いません。 Object Pascal は Pascal のスタイルを継承し、プログラムの美的意味に重点を置いています。コンパイラーは、プログラマーが複雑な作業を完了するのに役立ちます。