작은 라이브러리를 코딩 중이며 예외 처리를 디자인하는 데 문제가 있습니다. 나는 C ++ 언어 의이 기능으로 혼란스러워하고 예외 클래스를 올바르게 사용하기 위해해야 할 일을 이해하기 위해 주제에 대해 가능한 한 많이 읽으려고했습니다.
클래스 system_error
의 STL 구현에서 영감을 얻은 일종의 접근 방식 을 사용하기로 결정했습니다 future_error
.
오류 코드가 포함 된 열거 형이 있습니다.
enum class my_errc : int
{
error_x = 100,
error_z = 101,
error_y = 102
};
단일 예외 클래스 ( 모델 error_category
의 구조와 system_error
모델에 필요한 모든 것에 의해 백업 됨 ) :
// error category implementation
class my_error_category_impl : public std::error_category
{
const char* name () const noexcept override
{
return "my_lib";
}
std::string message (int ec) const override
{
std::string msg;
switch (my_errc(ec))
{
case my_errc::error_x:
msg = "Failed 1.";
break;
case my_errc::error_z:
msg = "Failed 2.";
break;
case my_errc::error_y:
msg = "Failed 3.";
break;
default:
msg = "unknown.";
}
return msg;
}
std::error_condition default_error_condition (int ec) const noexcept override
{
return std::error_condition(ec, *this);
}
};
// unique instance of the error category
struct my_category
{
static const std::error_category& instance () noexcept
{
static my_error_category_impl category;
return category;
}
};
// overload for error code creation
inline std::error_code make_error_code (my_errc ec) noexcept
{
return std::error_code(static_cast<int>(ec), my_category::instance());
}
// overload for error condition creation
inline std::error_condition make_error_condition (my_errc ec) noexcept
{
return std::error_condition(static_cast<int>(ec), my_category::instance());
}
/**
* Exception type thrown by the lib.
*/
class my_error : public virtual std::runtime_error
{
public:
explicit my_error (my_errc ec) noexcept :
std::runtime_error("my_namespace ")
, internal_code(make_error_code(ec))
{ }
const char* what () const noexcept override
{
return internal_code.message().c_str();
}
std::error_code code () const noexcept
{
return internal_code;
}
private:
std::error_code internal_code;
};
// specialization for error code enumerations
// must be done in the std namespace
namespace std
{
template <>
struct is_error_code_enum<my_errc> : public true_type { };
}
오류 코드 열거로 설명 된 예외가 발생하는 상황은 적습니다.
위의 리뷰어 중 하나와 잘 맞지 않았습니다. 그는 std::runtime_error
조건에 포함 된 오류 코드가 예외와 오류 코드를 혼합하여 사물을 혼합하기 때문에 파생 된 기본 클래스를 사용하여 예외 클래스의 계층 구조를 만들어야한다고 생각 했습니다. 취급 예외 계층 구조는 오류 메시지를 쉽게 사용자 정의 할 수있게합니다.
내 주장 중 하나는 내 라이브러리 예외의 여러 유형을 던질 필요가 없었다 것으로, 간단하게하고 싶다고했고이 자동으로 처리함에 따라 사용자 정의는이 경우 쉽게도 있음 -가 error_code
있다 error_category
변환 그와 연관된 올바른 오류 메시지를 표시하십시오.
나는 C ++ 예외에 대해 여전히 오해가 있다는 사실을 증명하면서 내 선택을 잘 지키지 않았다고 말해야합니다.
내 디자인이 의미가 있는지 알고 싶습니다. 내가 인정하지 않아도 선택한 방법에 비해 다른 방법의 장점은 무엇입니까? 개선하기 위해 무엇을 할 수 있습니까?