web-dev-qa-db-ja.com

std :: exceptionから継承する正しい方法

例外階層を作成し、派生クラスのコンストラクターに_char*_を渡して、何が間違っているかを伝えるメッセージを渡したかったのですが、明らかに_std::exception_にはそうすることができるコンストラクターがありません。しかし、what()と呼ばれるクラスメンバがあり、いくつかの情報を渡すことができることを示唆しています。
例外クラスの情報を渡すために_std::exception_の派生クラスにテキストを渡すには(どうすればよいですか)、コードのどこかで次のように言えます。

_throw My_Exception("Something bad happened.");
_
50
smallB

文字列コンストラクタを使用する場合は、 std :: runtime_error または std :: logic_error から継承する必要があります。これは、文字列コンストラクタを実装し、std :: exceptionを実装します。 ::どのような方法。

次に、新しい継承クラスからruntime_error/logic_errorコンストラクターを呼び出す場合、またはc ++ 11を使用している場合はコンストラクター継承を使用できます。

53
obmarg

例外には次のクラスを使用しますが、正常に機能します。

class Exception: public std::exception
{
public:
    /** Constructor (C strings).
     *  @param message C-style string error message.
     *                 The string contents are copied upon construction.
     *                 Hence, responsibility for deleting the char* lies
     *                 with the caller. 
     */
    explicit Exception(const char* message):
      msg_(message)
      {
      }

    /** Constructor (C++ STL strings).
     *  @param message The error message.
     */
    explicit Exception(const std::string& message):
      msg_(message)
      {}

    /** Destructor.
     * Virtual to allow for subclassing.
     */
    virtual ~Exception() throw (){}

    /** Returns a pointer to the (constant) error description.
     *  @return A pointer to a const char*. The underlying memory
     *          is in posession of the Exception object. Callers must
     *          not attempt to free the memory.
     */
    virtual const char* what() const throw (){
       return msg_.c_str();
    }

protected:
    /** Error message.
     */
    std::string msg_;
};
59
tune2fs

これはどう:

class My_Exception : public std::exception
{
public:
virtual char const * what() const { return "Something bad happend."; }
};

または、必要に応じて説明を受け入れるコンストラクタを作成します...

7
user472155

一般的な例外をスローしないように例外を作成することが目標( cpp:S112 )の場合、継承する例外を公開したいだけです( C++ 11 )using宣言あり。

そのための最小限の例を次に示します。

#include <exception>
#include <iostream>

struct myException : std::exception
{
    using std::exception::exception;
};

int main(int, char*[])
{
    try
    {
        throw myException{ "Something Happened" };
    }
    catch (myException &e)
    {
        std::cout << e.what() << std::endl;
    }
    return{ 0 };
}

Kilianがコメントセクションで指摘しているように、この例は、std :: exceptionの特定の実装に依存しており、言及されているよりも多くのコンストラクタを提供します here

これを避けるために、ヘッダー<stdexcept>。これらの「 例外カテゴリ 」を参考にしてください。

5
Johannes

whatメソッドは仮想であり、その意味は、返すメッセージを返すためにオーバーライドする必要があるということです。