2017-02-06 7 views
1

私のcsクラスの私の割り当ては、std :: logic_errorから継承した2つのカスタム例外クラスを作成することです:OverflowingSwimmingPoolExceptionとUnderflowingSwimmingPoolException。不正な操作が試行されると、エラーメッセージを出力するのではなく、カスタム例外を作成してスローします。 try ... catchブロックをドライバコードに含めて、例外をキャッチします。は、std :: logic_errorから継承する2つのカスタム例外クラスを作成できません。

これは私のヘッダファイルの一部です:用 コンストラクタ「CS52 :: UnderflowingSwimmingPoolExceptionは、」明示的に基底クラスのSTDを初期化する必要があります。ここに

#ifndef SWIMMINGPOOL_H 
    #define SWIMMINGPOOL_H 
    #include <stdexcept> 
    #include <iostream> 
    using namespace std; 



namespace cs52 
    { 
      class OverflowingSwimmingPoolException: public logic_error 
    { 

    OverflowingSwimmingPoolException(){}; 

}; 

class UnderflowingSwimmingPoolException: public logic_error 
{ 

    UnderflowingSwimmingPoolException(){}; 
}; 

コンパイラは、コンストラクタがある行に言うされています。 :logic_error 'にはデフォルトのコンストラクタがありません。

私は私の実装ファイルに持っているものです。

#include "SwimmingPool.h" 
    #include <stdexcept> 
    #include <iostream> 
    using namespace std; 



    namespace cs52 
    {  
     SwimmingPool operator +(const SwimmingPool& pool1, const SwimmingPool&   pool2) throw (OverflowingSwimmingPoolException, UnderflowingSwimmingPoolException) 
{ 
    SwimmingPool temp; 
    temp.mySize = pool1.mySize+pool2.mySize; 
    temp.myContents = pool1.myContents+pool2.myContents; 
    if (temp.myContents>temp.mySize) 
    throw OverflowingSwimmingPoolException(); 
    return temp; 
} 
SwimmingPool operator -(const SwimmingPool& pool1, const SwimmingPool& pool2) throw (OverflowingSwimmingPoolException, UnderflowingSwimmingPoolException) 
{ 
    SwimmingPool temp; 
    temp.mySize= pool1.mySize-pool2.mySize; 
    temp.myContents= pool1.myContents-pool2.myContents; 
    if (temp.myContents>temp.mySize) 
     throw OverflowingSwimmingPoolException(); 
    if (temp.myContents<0 || temp.mySize<0) 
     throw UnderflowingSwimmingPoolException(); 
    return temp; 
} 
} 

コンパイラが、私は例外クラスをスローラインにエラーが表示されます。クラスcs53:OverflowingSwimmimgPoolExceptionのプライベートコンストラクタを呼び出します。

と私のドライバファイルの一部は、そのようなことになります。

using namespace cs52; 
    try { 
    SwimmingPool badPool = smallOne - bigOne; 
    cout << "This should never happen..." << endl; 
    } 
    catch(UnderflowingSwimmingPoolException uspe) { 
    cout << "working..." << endl; 
    } 
    catch(OverflowingSwimmingPoolException uspe) { 
    cout << "This should never happen..." << endl; 
    } 

私はコードに開始しているので、私は本当に理解していないがどのようにすでに作成されているのstd :: logic_errorのようなクラスライブラリは機能します。派生例外のコンストラクタで

答えて

1

、あなたはこのように、基底クラス、which takes a string containing some error textのコンストラクタを呼び出す必要があります。

OverflowingSwimmingPoolException() 
    : std::logic_error("It's all gone horribly wrong!") 
{}; 

あなたは(あなたを想定してキャッチした例外にwhat()を呼び出したときにこれが返されます

try { 
    // ... 
} catch (std::exception const& e) { 
    std::cerr << e.what() << '\n'; // Prints "It's all gone horribly wrong!" 
} 

それは除いてのインタフェースのための一般的です。)しかし、それをしない、異なる行動でそれを上書きしません。イオンタイプは、この目的のために文字列を取るが、あなた自身の例外タイプのために、あなたはする必要はありません。

catch基本クラスを使用した例外の場合は、を避けるために、参照(またはconstの参照)でキャッチすることを確認してください。

1

エラーは非常に明確で、ロジック、いつ、どこで、どのように例外をスローするかは関係ありません。それは、例外クラス自体とコンストラクタについてです。

親クラスを初期化する必要があるとエラーが通知する方法に注意してください。例えば、次のようなコンストラクタの初期化子リストを使ってそれを行うことができます。

OverflowingSwimmingPoolException() 
    : std::logic_error("Some error message") 
{} 

std::logic_error初期化中のエラーメッセージがwhat機能が報告されますものです。

+0

ありがとう!それは助けになった! – Marina

+0

今私は別の問題があります。何らかの理由で、tryブロック内のメンバ関数を使用しても、オブジェクトの変数は変更されません。私がtryブロックから同じメンバ関数を使用すると、それは完全に正常に動作します!あなたは何が間違っているか考えていますか? – Marina

+0

@マリナどのコードも見ることができないと、問題が何であるかを言うことができません。新しい問題はこの問題とは無関係であるため、別の質問として投稿してください。もちろん、[最小限で完全で検証可能な例](http://stackoverflow.com/help/mcve)も含まれています。また、問題が解決された回答(最小または他の誰かから)があると感じる場合は、回答の横にあるチェックマークをクリックして「受け入れ済み」とマークする必要があります。 –

0

std::logic_errorが初期化中に引数を必要とするため、コンパイラのメッセージで「デフォルトのコンストラクタを持たない基本クラス 'std :: logic_error'を明示的に初期化する必要があります」というメッセージがあります。具体的には、文字列が必要です。たとえば、次のように

class my_exception: public std::logic_error { 
    my_exception() { }; 
} 

...動作しませんが...

class my_exception: public std::logic_error { 
    my_exception(const char* what): std::logic_error(what) { }; 
} 

...意志コンストラクタstd::logic_error::logic_error()はありませんが、1つstd::logic_error::logic_error(const char*)がありますので。

あなたが特定の例外クラスの静的(whatで与えられる)例外「理由」を指定したい場合は、すべての標準の例外を継承し、このような...

class my_exception: public std::logic_error { 
    my_exception(): std::logic_error("Oh No!") { }; 
} 

として建設中にそれを指定することができますstd::exceptionから、例外の理由が予期されます。後で、この理由は次のように使用できます。

try { 
    throw my_exception(); 
} catch (const std::exception& e) { // << because you inherited this class 
    std::cerr << "error: " << e.what() << std::endl; 
} 

... "error:Oh No!"と表示されます。前の例を使用してください。

具体的には、std::logic_errorstd::exceptionを参照してください。

関連する問題