2017-01-04 4 views
1

私はクラスを返すことを意味する関数を持っているとしましょう。しかし、コンストラクタを呼び出すときに例外処理を使いたいと思います。問題は、ある例外の場合には、私は返すように望んでいたクラスは範囲外であると私は返すことは何もない:例外処理を持つ関数のクラスを返す

myclass GetClass() { 
    try { 
     myclass classtoreturn(7); 
     return classtoreturn; 
    } catch (const std::exception& ex) { 
     // 
    } catch (const std::string& str) { 
     // 
    } catch (...) { 
     // 
    } 

    return ??; 
} 

しかし、私はのtry/catchの外でクラスを宣言した場合、私は返すように初期化されていないクラスの問題を持っているつもり:

myclass GetClass() { 
    myclass classtoreturn; 
    try { 
     classtoreturn(7); 
     return classtoreturn; 
    } catch (const std::exception& ex) { 
     // 
    } catch (const std::string& str) { 
     // 
    } catch (...) { 
     // 
    } 

    return classtoreturn; //Unitialized! 
} 

私の最初のinstictではなくポインタを返すと、例外が発生した場合にNULLポインタを返すようにしたが、その後ポインタが指しされるだろうスコープ外のクラスで、これはまだ良くありません。このようなことはよくある問題ですが、私は解決策を見つけたわけではありません。

また、実際のアプリケーションはhereと表示されます。ここではgpsmmクラスをメイン関数に戻してポーリング関数へのポインタとして渡すことができます。

ありがとうございます!


OK、今私はしかし、私はこれは単に呼び出し側に問題をpropogatesだと思う、それは呼び出し側で例外をキャッチすることは理にかなって思っているいくつかの回答を読んで:私として

void main() { 
    try{ 
     myclass classforuse{ GetClass() }; 
    } catch (...) { 
     // 
    } 

    //Want to do something with "classforuse" but it's out of scope! 
} 

私が宣言するときにクラスが構築されることを理解しているので、try {}内からクラスを作成し、std/boost :: optionalを使用せずに同じtry {}の範囲外で使用する方法はありません。あれは正しいですか?私は同じtry {}の中からクラスを使用する実用的な手段が見つからない限り、boostライブラリは私の唯一の選択肢だと思う。ありがとう

+0

'std :: optional'または' boost :: optional'を見てください。 – Holt

答えて

2

これを処理する方法はいくつかあります。最初は関数の戻り値の型を返すように変更し、クラスを値で返す代わりにstd::unique_ptrで渡します。 std::unique_ptrはnullでもかまいません。例外がある場合はnullを返します。そうでない場合は、作成したオブジェクトにunique_ptrを返します。

もう1つのオプションは、boost::optionalまたはstd::optionalです。今すぐboost::optionalを使用することができますが、std::optionalはC++ 17の機能ですので、利用可能な数は限られています。個人的には、オプションのアプローチは、タイプによってちょうどその状況をより詳しく説明しています。 optionalには、動的メモリ割り当てがないという追加の利点もあります。

最後に、回復できず、関数をスローすることができませんでした。これは、何か起きたことを呼び出し側に伝え、返されたオブジェクトを取得しませんでした。

0

catchは間違って見えます。クライアントコードで例外をキャッチするか、再スローすることを検討してください。それ以外の場合、関数は正常に作成されたオブジェクトを復元して返すことができるはずです。

1

例外が発生した場合、あなたの関数は有効なmyclassオブジェクトを返すという義務を果たしておらず、あなたはそれをどう扱うかわかりません。例外をスローする最初の解決策、おそらく失敗に終わったもの。 catchブロック内にある間に、空のthrow;ステートメントを使用して同じ例外を再発行することができます。

catch(const std::exception & err) { 
    // do whatever it is you need to do (logging?) 
    throw; // this statement throws 'err' again 
} 
あなたは(あなたのcatchブロックが空であるが、それは簡潔にするためであるかもしれない)あなたはここでの問題を解決できない場合は、通常、しかし、これらの例外を除いて何かをすることが予想される場合は、私は知らない

、ドン」例外をキャッチしようとしないでください。 try/catch全体を削除し、例外を伝播させてください。

あなたの関数からの投げ込みが受け入れられない場合は、関数をmyclass以外の値に戻す必要があります。 C++へのアクセス権がある場合は、std::optionalまたは同様のラッパーの使用を検討してください。