3

std::exception最近、すべての例外の基本クラスとして使用し始めました。キーワードを前にwhat()置かないと、適切にオーバーライドできませんでした。キーワードがvirtualないと、常に基本クラスの関数を呼び出すように見えました。virtualwhat()std::exception

virtual関数をオーバーライドするときに関数の前に置く必要はないと思っていたので、少し当惑しました(そして、それを確認するように見える投稿があります)。しかし、私はそれを手放して先に進むことにしました。

それから今日、O'Reilly の "Safe C++" を読んでいるときに、著者もwhat()virtual キーワードでオーバーライドしているのを見つけました。彼が書きました...

virtual const char* what() const throw () { /* stuff */ }

なぜ彼は関数をオーバーライドしてvirtualキーワードを使用しているのですか? 上で引用した投稿で提案されているように、それは「ドキュメント」のためだけですか?

4

1 に答える 1

3

サブクラスの実装を呼び出すために、what()のオーバーライドの前にvirtualキーワードを置く必要はありません。おそらく、それが基本クラスの実装を呼び出していることを発見したとき、参照していた例外オブジェクトが、例外の不適切なパスを介してスライスされていたのでしょうか。たとえば、私は常に参照によってキャッチします(Scott Meyersの推奨に従って)が、例外値によってキャッチし、スローされる可能性のあるサブクラスのスーパークラスとしてキャッチを宣言した場合、オブジェクトはキャッチしたときにスライスされます。言い換えると、この例外サブクラスを宣言した場合:

class my_exception : public std::exception
...

そして私はそのようなインスタンスをキャッチしました:

try
{
    ...
    throw my_exception("Some message");
}
catch (std::exception e)
{
    ...
}

ecatchブロックには、スライスされたオブジェクトがあります。次のような例外をキャッチする必要があります。

try
{
    ...
    throw my_exception("Some message");
}
catch (std::exception& e)
{
    ...
}
于 2012-11-07T11:21:44.767 に答える