2017-10-23 13 views
5

エラー:終了「* char型のconst」のインスタンスを投げた後に呼び出さ例外++終了「* char型のconst」のインスタンスを投げた後に呼び出さ

は、アプリケーションを終了は珍しいでそれを終了するランタイムを要求されています方法。アプリケーションのサポートチームにお問い合わせください。

これを実行すると、コンパイラがクラッシュする原因がわかりません。何か案は?プログラミングに少し慣れています。

#include <iostream> 
#include <iomanip> 

using namespace std; 

//Template for Maximum 

template <class X> 
X Maximum(X arg1, X arg2) 
{ 
    if (arg1 > arg2) 
     return arg1; 
    else 
     return arg2; 
} 

//Template for Minimum 

template <class M> 
M Minimum(M arg1, M arg2) 
{ 
    if (arg1 > arg2) 
     return arg2; 
    else 
     return arg1; 
} 

/* Template for Divide(D arg1, D arg2) arg1: the dividend arg2: the divisor Description: 
Divides arg1 by arg2. If arg2 equals zero then an exception is thrown. */ 

template <class D> 
D Divide(D arg1, D arg2) 
{ 
    if (arg2 == 0) { 
     throw "You cannot devide by zero! "; 
    } 
    return (arg1/arg2); 
} 

int main() 
{ 

    int a, b; 
    float c, d; 
    double e, f; 
    a = 2; 
    b = 22; 
    cout << setprecision(4) << fixed << showpoint << "min:" << Minimum(a, b) << "\tmax: " << Maximum(a, b) << endl; 
    c = 4.7f; 
    d = 2.97f; 
    cout << setprecision(4) << fixed << showpoint << "min:" << Minimum(c, d) << "\tmax: " << Maximum(c, d) << endl; 

    e = 387.78; 
    f = 387.7798; 
    cout << setprecision(4) << fixed << showpoint << "min:" << Minimum(e, f) << "\tmax: " << Maximum(e, f) << endl; 
    e = 40; 
    f = 0; 
    try { 
     cout << setprecision(4) << fixed << showpoint << "Divide: " << e << '/' << f << " = " << Divide(e, f) << endl; 
    } 
    catch (string exceptionString) { 
     cout << exceptionString; 
    } 
    system("pause"); 
    return 0; 
} 
+1

あなたは 'std :: string'をキャッチしようとしていますが、あなたは' std :: string'を投げません。あなたは 'const char *'を投げます。あなたのプログラムは、キャッチされない例外のために終了します。 –

+1

何かを投げることは許されていますが、そうしないでください。 std :: runtime_errorを使用するか、std:.exceptionまたはその子孫から派生します。キャッチ 'const std :: exception&' –

答えて

4

文字列リテラルはstd::stringではありません。あなたは前者を投げますが、後者を捕らえようとします。 std::stringが文字列リテラルから構成されているにもかかわらず、catch節では発生しません。 catch節で許可されている変換は[except.handle]/3に詳述されている:

ハンドラはタイプEの例外オブジェクトの一致である場合:

  • ハンドラタイプCV TまたはCV Tであります&はE及びTは、同じタイプ(トップレベルCV-修飾子を無視する)であるか、または
  • ハンドラタイプCV TまたはCV T &であり、Tは、
  • Eの明確な公共基底クラスであり、又はハンドラは型cv Tまたはconst TであるTはメンバー型へのポインタまたはポインタであり、Eは
    • の一つ以上のプライベートへのポインタへの変換を伴わない標準のポインタ変換によってTに変換することができるメンバー型 へのポインタまたはポインタであるか、または保護またはあいまいなクラス
    • 関数ポインタ変換
    • 資格変換、または
  • ハンドラは、Tは、メンバー型へのポインタまたはポインタであるタイプCV TまたはCONST T &であり、Eは、STDであります:: nullptr _t。

そして、どちらのはリテラルの場合に適用される - >std::string変換。

これは最終的にその例外がキャッチされず、実行時呼び出しstd::terminate asはキャッチされない例外が発生することになっています。

一般に、例外タイプ(階層の一部である可能性があります)をスローすると、発生したエラーが非常に型名に伝達されるのが最善です。これにより、ハンドラ(またはハンドラのセット)を記述する必要がある場合に、より堅牢な方法でエラーを処理できます。

何らかの理由で標準の方法に従わない場合は、上記の箇条書きに記載されている変換の1つに変換する必要があります。次のいずれかが可能です。

  1. は(sサフィックスに注意してください)"You cannot devide by zero!"sのように、std::string literal投げます。
  2. キャッチa const char*
+0

ああ、完璧な意味があります。詳しい説明はありがとうございます。それは有り難いです。 – Chad

関連する問題