在 C++ 异常的 what() 中构建字符串
String building in C++ exception’s what()
This answer 声明一个 private static ostringstream
。这个线程安全吗?如果两个线程同时抛出(捕获并记录 what()
)异常,这是否可靠?如果我在本地声明 ostringstream
,例如:
virtual const char* what() const throw()
{
std::ostringstream cnvt.str( "" );
cnvt << runtime_error::what() << ": " << getNumerator()
<< " / " << getDenominator();
return cnvt.str().c_str();
}
是否存在缺陷(内存泄漏,或非法指针)?或者这是线程安全的方式?
没有。它根本不安全(而且对我来说效率很低,可以单独使用 std::string
来完成)。
为了安全起见,将 ostringstream
声明为 thread_local
static thread_local ostringstream cnvt;
此外,您应该使 cnvt
将字符串输出到某个成员字符串,以免 return 成为悬空指针。
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;
};
此外,如果异常是 "divide by zero",您不认为存储分母有点傻吗?它始终为零!否则你不会抛出 "division by zero" 错误!
最后0分误差更适合从与数学误差相关的std::domain_error
导出。
what()
是构建字符串恕我直言的错误位置(尽管对此有不同的看法)。
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));
}
};
This answer 声明一个 private static ostringstream
。这个线程安全吗?如果两个线程同时抛出(捕获并记录 what()
)异常,这是否可靠?如果我在本地声明 ostringstream
,例如:
virtual const char* what() const throw()
{
std::ostringstream cnvt.str( "" );
cnvt << runtime_error::what() << ": " << getNumerator()
<< " / " << getDenominator();
return cnvt.str().c_str();
}
是否存在缺陷(内存泄漏,或非法指针)?或者这是线程安全的方式?
没有。它根本不安全(而且对我来说效率很低,可以单独使用 std::string
来完成)。
为了安全起见,将 ostringstream
声明为 thread_local
static thread_local ostringstream cnvt;
此外,您应该使 cnvt
将字符串输出到某个成员字符串,以免 return 成为悬空指针。
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;
};
此外,如果异常是 "divide by zero",您不认为存储分母有点傻吗?它始终为零!否则你不会抛出 "division by zero" 错误!
最后0分误差更适合从与数学误差相关的std::domain_error
导出。
what()
是构建字符串恕我直言的错误位置(尽管对此有不同的看法)。
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));
}
};