2015-12-15 4 views
5

。 ClassAにデフォルトのコンストラクタ​​がなく、ポインタを使用したくないとすれば、どうすれば実現できますか? ClassAにデフォルトのコンストラクタを追加する唯一の方法はありますか?アクセス変数Iは、次のコードを持って外のtry-catchブロックを

+3

「try」ブロックに入れてみませんか?例外をスローすると、とにかく「終了」します。 – MatthewRock

+3

質問は意味をなさない: 'a'の構築が例外を投げた場合、' a'はとにかく役に立たない。 –

+2

'catch 'には後にstuffが必要です。 'catch(...)' –

答えて

9

あなたはそうすることはできません。代わりに、あなただけのtryブロック内でそれを使用することができ、何かのように:あなたはポインタを持っている場合

try 
{ 
    ClassA a = ClassA(s); 

    std::string result = a.GetSomething(); 
} 
catch(...) 
{ 
    //Do something 
    exit(1); 
} 

理由(オブジェクトを参照するtryブロックの後にスコープ外になるaので、それは未定義の動作がされた後ということですそれがどこにあったか)。

あなたがa.GetSomethingまたは割り当てthrow Sに関係している場合は、その周りのtry-catchを置くことができます:

try 
{ 
    ClassA a = ClassA(s); 

    try { 
     std::string result = a.GetSomething(); 
    } 
    catch(...) { 
     // handle exceptions not from the constructor 
    } 
} 
catch(...) 
{ 
    //Do something only for exception from the constructor 
    exit(1); 
} 
5

あなたはoptionalのいくつかの並べ替えを使用するか、単にstd::unique_ptrを使用することができます。もちろん

int main() 
{ 
    std::string s = ""; 
    std::unique_ptr<ClassA> pa; 
    try 
    { 
     pa.reset(new ClassA(s)); 
    } 
    catch 
    { 
     //Do something 
     exit(1); 
    } 

    ClassA& a = *pa; // safe because of the exit(1) in catch() block 
    std::string result = a.GetSomething(); 

    //Some large amount of code using 'a' out there. 
} 
2

、ちょうどaの使用を含むようにtryブロックを拡張は、最も単純な解決策です。

また、実際にexit(1)に計画していた場合、または失敗した場合にプログラムを中止した場合は、tryブロックをここに配置しないでください。例外が伝播し、プログラムがキャッチされない場合は中止されます。


std::optionalを使用することもできます。これはポインターを使用するのと同じ概念ですが、自動割り振りを使用するため、メモリーリークを起こす可能性は低くなります。これは現在実験ステータスです。

#include <experimental/optional> 
using std::experimental::optional; 
using std::experimental::in_place; 

// ... 

    optional<ClassA> a; 

    try 
    { 
     a = optional<ClassA>(in_place, s); 
    } 
    catch(...) 
    { 
     // display message or something 
    } 

    std::string result; 
    if (a) 
     result = a->GetSomething(); 

これはスパゲッティスタイルのビットであり、あなたのように、異なったあなたのコードを設計する方が良いだろうとけれども、私は改めてしたい:あなたのコンパイラがstd::experimental::optionalを持っていない場合、代わりにboost::optionalを使用することができます建設が成功したか失敗したかを継続的にテストしていません。

ClassAは、移動またはコピー可能である必要があります。 in_placeは、残りの引数に対して完全な転送コンストラクタを呼び出す特殊な引数です。 in_placeを指定しないと、コンストラクターの引数として実際にClassAしか指定できません。暗黙の変換はClassAには考慮されません。 (これは、optionalが同じタイプのオブジェクトからのコピー構築とリスト初期化のあいまいさを避ける方法です)。

関連する問題