为什么 Quantlib::Error class 在堆上分配一个 std::string ?
Why does the Quantlib::Error class allocate a std::string on the heap?
在最近的一次代码审查中,我对一些我认为很糟糕的事情说了一些不太客气的话。原来明显是受到了QuantLib::Errorclass的启发,长这样:
//! Base error class
class Error : public std::exception {
public:
/*! The explicit use of this constructor is not advised.
Use the QL_FAIL macro instead.
*/
Error(const std::string& file,
long line,
const std::string& functionName,
const std::string& message = "");
#ifdef QL_PATCH_MSVC_2013
/*! the automatically generated destructor would
not have the throw specifier.
*/
~Error() throw() override {}
#endif
//! returns the error message.
const char* what() const QL_NOEXCEPT override;
private:
ext::shared_ptr<std::string> message_;
};
为什么成员变量是ext::shared_ptr<std::string>
而不是普通的std::string
?堆分配字符串对象本身的原因是什么? (QuantLib 代码库似乎几乎总是在任何地方堆分配所有内容,并引入 shared_ptr
来应对这种情况 - classic 反模式 - 但在这里做还有“只是为了保持一致性”让我觉得有点过分。我错过了什么吗?)
这是遵循标准库异常类型的行为。
它们应该可以在不抛出异常的情况下进行复制,因为在构造异常处理程序参数期间抛出异常会导致调用 std::terminate
(并且可能在某些其他情况下需要异常的副本作为嗯)。
如果直接使用 std::string
,复制异常可能会导致例如 std::bad_alloc
被抛出。使用 reference-counted 指针可以避免这种情况。
在最近的一次代码审查中,我对一些我认为很糟糕的事情说了一些不太客气的话。原来明显是受到了QuantLib::Errorclass的启发,长这样:
//! Base error class
class Error : public std::exception {
public:
/*! The explicit use of this constructor is not advised.
Use the QL_FAIL macro instead.
*/
Error(const std::string& file,
long line,
const std::string& functionName,
const std::string& message = "");
#ifdef QL_PATCH_MSVC_2013
/*! the automatically generated destructor would
not have the throw specifier.
*/
~Error() throw() override {}
#endif
//! returns the error message.
const char* what() const QL_NOEXCEPT override;
private:
ext::shared_ptr<std::string> message_;
};
为什么成员变量是ext::shared_ptr<std::string>
而不是普通的std::string
?堆分配字符串对象本身的原因是什么? (QuantLib 代码库似乎几乎总是在任何地方堆分配所有内容,并引入 shared_ptr
来应对这种情况 - classic 反模式 - 但在这里做还有“只是为了保持一致性”让我觉得有点过分。我错过了什么吗?)
这是遵循标准库异常类型的行为。
它们应该可以在不抛出异常的情况下进行复制,因为在构造异常处理程序参数期间抛出异常会导致调用 std::terminate
(并且可能在某些其他情况下需要异常的副本作为嗯)。
如果直接使用 std::string
,复制异常可能会导致例如 std::bad_alloc
被抛出。使用 reference-counted 指针可以避免这种情况。