2012-03-28 13 views
0

オブジェクトのメモリを割り当てています。メモリ割り当てに失敗した特定のステートメントが失敗した場合は、メモリを削除して例外をスローする必要があります。例えばC++プログラミングtry catch

はどこでどのように例外がスローされた場合、私は、クエリを削除する必要があります。ここ

   QSqlQuery *query = new QSqlQuery(db); 
       try { 
       query->prepare(somestmt); 
       } 
       catch (...) { 
       throwException(*query); 
       } 

を言うの?

ありがとうございます!

答えて

2

答えは、クエリオブジェクトが存続するために必要な時間によって異なります。あなたがtry/exceptブロックの外にそれを必要としないならば、ブロックを離れるとすぐにRAIIを使って削除するのが最善でしょう。

try { 
    boost::scoped_ptr<QSqlQuery> query(new QSqlQuery(db)); 
    query->prepare(somestmt); 
} 
catch (...) { 
    throwException(); 
} 

をしかし、あなたの周りにそのブロックを過ぎて、クエリオブジェクト、またはそれのコピーを保存しておきたいようなあなたの例から、それが見えます:例えば、ブースト:: scoped_ptrをを使用して、あなたはこれを行うことができます。あなたは、元のを維持する必要がある場合は

QSqlQuery* query = new QSqlQuery(db); 
try { 
    query->prepare(somestmt); 
} 
catch (...) {   
    QSqlQuery copyOfQuery(*query); 
    delete query; 
    throwException(copyOfQuery); 
} 
delete query; 

:あなたはブーストを使用して好きではない場合は、これを

boost::scoped_ptr<QSqlQuery> query(new QSqlQuery(db)); 
try { 
    query->prepare(somestmt); 
} 
catch (...) {   
    QSqlQuery copyOfQuery(*query); 
    throwException(copyOfQuery); 
} 

または:それはちょうどそれのコピーを保持しても大丈夫だ場合は、これを行うことができますそれ自身を照会すると、それを削除するためには例外オブジェクト自体を必要とするでしょう。すなわち、このような何か:

QSqlQuery* query = new QSqlQuery(db); 
try { 
    query->prepare(somestmt); 
} 
catch (...) {   
    throw MyException(query); 
} 
delete query; 
「MyException」の契約の一部が、それはその引数の所有権を取ることである

(すなわち、それを削除するための責任)。

共有ポインターを使用することもできます。これは、最後の共有ポインタがなくなるとクエリが削除されるという利点があり、メモリ管理がはるかに容易になります。

+0

woof! ;)あなたは本当にすべて60秒で入力しましたか? +1良い答え – slashmais

+1

'boost :: scoped_ptr'と' boost :: shared_ptr'の代わりに 'std :: unique_ptr'と' std :: shared_ptr'を使うことができます。 – bames53

+0

驚くばかり!ありがとう、エドワード! – user1065969

0

これを正常に処理するには、RAIIを使用する必要があります。
生ポインタの代わりにスマートポインタを使用するか、リソース管理クラスを使用して割り当てられたポインタをラップし、スコープが終了したときに割り当てられたオブジェクトを解放するようにします。あなたは、準備して、それを削除しない有効であるためにポインタを必要とする再試行そうmemeoryを削除し、idealyそれを

編集をマークするためにnullにpoitnerを設定することができるかどう

+0

tryブロック内に2つのステートメントがあり、最初のステートメントが例外をスローした場合、2番目のステートメントは実行されますか? – user1065969

+0

@ user1065969:いいえ、それは一度スローされるとコントロールはキャッチハンドラに移動しません。 –

0

それは、あなたのプログラムに依存します。申し訳ありません誤解された質問 - 変更された回答

+0

これは例外をスローする新しいものではありません、それは準備していますstatemnet – user1065969

0

RAII patternを学ぶ必要があります。考え方は、デストラクタでクリーンアップを行うC++クラスにQSqlQueryをラップすることです。そのようにして範囲外になる場合(throw,returnのいずれか、またはブロックの終わりに達すると宣言されます)、それは完全に破棄されます。

+0

このクエリは私のためのローカル変数でなければなりません。 QScopedPointerクラスの変数があり、準備が成功したらこのクエリの所有権を譲渡します – user1065969

+0

tryブロック内に2つのステートメントがあり、最初のステートメントが例外をスローすると、2番目のステートメントが実行されますか? – user1065969

+0

@ user1065969:いいえ。 tryブロックは、例外が発生するとすぐに終了し、その後のステートメントは実行されません。 –

0

ここで通常のイディオムは、あなたのプログラムロジックが引き継ぐ に依存するものは何でものためにこれまで得てきたら、それ にresetを呼び出し、std::auto_ptrを使用することです。これにより、catchが不要になります。とにかく catchが必要なようです(例外を再マップするには) をdeleteに置き換えてstd::auto_ptrをスキップしてください。 (一方、1 はauto_ptrを見ることを期待し、それは質問をする読者 を引き起こす可能性があります持っていない。)

0

代わりにノークリーンアップ&hellipの。

  QSqlQuery *query = new QSqlQuery(db); 
      try { 
      query->prepare(somestmt); 
      } 
      catch (...) { 
      throwException(*query); 
      } 

ちょうどそれが(QSqlQueryが適切なデストラクタを持っていると仮定)だと

  QSqlQuery query(db); 
      try { 
       query.prepare(somestmt); 
      } 
      catch (...) { 
       throwException(query); 
      } 

を書きます。