0

私がこれを持っているとしましょう:

namespace MyNamespace{

class Exception : public std::runtime_error
{
public:
  explicit Exception(const std::string &msg) : std::runtime_error(msg) {}
};

} //namespace MyNamespace

そして、私のプログラムのどこかにコードがあります:

try{
    foo();
}
catch (const MyNamespace::Exception &exc){
    std::cout << exc.what();
}

質問は(私を調べてほしい)です-fooで書いた場合、例外をキャッチしますか:

1)throw MyNamespace::Exception("Hello world!");

ここで私は、はい、私は間違いなく例外のタイプを指摘したので(そしてそれは「明示的な」キーワードの必要な原因です)、 std::string には「明示的な」キーワードがないため、「こんにちは世界」をスローできると思います!」std::string("Hello world!") の代わりに

2)throw MyNamespace::Exception(std::string("Hello world!"));

明らかに、そうします。

3)throw "Hello world!";

ここでは、いいえ、そうしません。キーワードの「明示的な」存在の原因です。

4)throw std::string("Hello world");

いいえ(同じ理由)

および 5) 明示的なキーワードがなかった場合、3 ~ 4 のケースから期待されるのは誰ですか? (私はイエスと思う)

更新: 6) 一時オブジェクト std::string はいつ作成されますか? どの時点で?

4

3 に答える 3

2

1 ~ 4 の答えは正しいですが、その背後にある理由は少しずれています。

explicit3) これはキーワードとは関係ありません。後の式の型は でthrowありconst char[12]、規則によりスローされる例外の型は ですconst char*

explicit4) 繰り返しますが、実際には文字列コンストラクターとは何の関係もありません。スローされた型はstd::stringstd::string(参照があるかどうかにかかわらず) ハンドラーの型のみがそれをキャッチできます。

5) 明らかに、いいえ。

6) 例外がスローされたとき。

于 2013-10-22T10:47:29.593 に答える
2

3 ~ 5 の文言から、オーバーロードされた関数から最適な一致を選択して呼び出すかのように、C++throwが をステートメントに一致させようとしていると考えていることは明らかです。catchそうではありません。ステートメントは、throwステートメントとは別に考慮されますcatch-実際、キャッチコードが記述される前に関数fooとそのステートメントをコンパイルできるため、キャッチコードが最終的に探している型にthrowa を変換することを選択できません...std::stringそれについては知りません。

スローされる値のタイプは、パラメータ to のタイプに完全に依存します。throwこれは、式が なしで表示された場合、周囲のコンテキストで理解されるためthrowです。例えば:

void foo()
{
     ...
     throw XXX;
}

...と同じ型を投げます...

void foo()
{
     ...
     auto what_will_be_thrown = XXX;
     throw what_will_be_thrown;
}

const char*のような変換はキャッチ時に適用されstd::stringませが、(参照またはポインターの) パブリック基本クラスを介して派生型をキャッチできます。もちろん、const参照などを使用して型をキャッチすることもできます。

Re 6) - 値の型にException関係なく、他の関数呼び出しのタイミングと同様に、コンストラクターが呼び出される直前に作成されますが、この場合、スローされるオブジェクトは通常のメモリ領域とは別のメモリ領域に構築される場合があります。一致する catch ステートメントを探している間に発生するスタックの巻き戻しを生き残るように、スタックを呼び出します。ただし、これがコンパイラによってどのように編成されるかは、標準では指定されていません。

于 2013-10-22T11:09:12.430 に答える
1

3 と 4 の根拠が間違っているため、5 に対する答えも間違っています。理由は次のとおりです。

例外の場合catch、基本クラスへの変換を除いて、すべての変換は実行されません。したがって、 のサブクラスを除いcatch (Foo const&)て、 に変換可能なものは決してキャッチされません。コードがスローされたorをキャッチしないのは、そのためであり、コンストラクターとは関係ありません。FooFooexplicitstd::stringchar[]

于 2013-10-22T10:48:42.087 に答える