1

この回答private static ostringstream. このスレッドは安全ですか? what()2 つのスレッドが同時に例外をスロー (およびキャッチしてログに記録) した場合、これは確実に機能しますか? ostringstreamローカルで宣言すると、次のようになります。

virtual const char* what() const throw()
{
    std::ostringstream cnvt.str( "" );
    cnvt << runtime_error::what() << ": " << getNumerator()
         << " / " << getDenominator();
    return cnvt.str().c_str();
}

欠点 (メモリ リーク、または不正なポインター) はありますか? それとも、これはスレッドセーフな方法ですか?

4

2 に答える 2

4

いいえ、まったく安全ではありません(私の好みではかなり非効率的ですが、std::string単独で実行できます)。
安全にするために、 as を宣言しostringstreamますthread_local

static thread_local ostringstream cnvt;

また、cnvtダングリング ポインターを返さないように、出力を何らかのメンバー文字列への文字列にする必要があります。

class DivideByZeroException: public runtime_error {
public:

  DivideByZeroException(int x, int y)
    : runtime_error( "division by zero" ), numerator( x ), denominator( y )
    {}

  virtual const char* what() const throw()
  {
    cnvt.str( "" );

    cnvt << runtime_error::what() << ": " << getNumerator()
         << " / " << getDenominator();

    error = cnvt.str();
    return error.c_str();
  } 

   /*...*/

   private:
     std::string error;
     int numerator;
     int denominator;

   static thread_local ostringstream cnvt;
};

また、例外が「ゼロ除算」の場合、分母を格納するのは少しばかげていると思いませんか? それは常にゼロです!それ以外の場合は、「ゼロ除算」エラーをスローしません!

std::domain_error最後に、数学的誤差に関連するものから導き出すには、0 除算誤差の方が適切です。

于 2016-09-12T11:32:05.593 に答える
1

what()文字列 IMHO を作成するのに間違った場所です (ただし、これにはさまざまな見方があります)。

std::runtime_errorすでに文字列が含まれているので、それを使用しましょう。

#include <stdexcept>
#include <string>

struct DivideByZero : std::runtime_error
{

    DivideByZero(int x, int y)
    : std::runtime_error( make_message(x,y) )
    {}

private:
    static std::string make_message(int x, int y)
    {
        return std::string("division by zero: " + std::to_string(x) + '/' + std::to_string(y));
    }

};
于 2016-09-12T11:50:45.267 に答える