ฉันกำลังเขียนโค้ดไลบรารีขนาดเล็กและฉันมีปัญหากับการออกแบบการจัดการข้อยกเว้น ฉันต้องบอกว่าฉันยังคงสับสนกับคุณสมบัติของภาษา 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 ++
ฉันต้องการทราบว่าการออกแบบของฉันเหมาะสมหรือไม่ อะไรคือข้อดีของวิธีอื่นที่ฉันเลือกเพราะฉันต้องยอมรับว่าฉันไม่เห็นด้วย? ฉันจะปรับปรุงอะไรได้บ้าง