Saya sedang mengode perpustakaan kecil dan saya mengalami masalah dengan merancang penanganan pengecualian. Saya harus mengatakan bahwa saya (masih) bingung dengan fitur bahasa C ++ ini dan saya mencoba membaca sebanyak mungkin tentang masalah ini untuk memahami apa yang harus saya lakukan untuk bekerja dengan benar dengan kelas pengecualian.
Saya memutuskan untuk menggunakan system_error
jenis pendekatan yang mengambil inspirasi dari implementasi future_error
kelas STL .
Saya memiliki enumerasi yang berisi kode kesalahan:
enum class my_errc : int
{
error_x = 100,
error_z = 101,
error_y = 102
};
dan satu kelas pengecualian (didukung oleh error_category
jenis struktur dan segala sesuatu yang dibutuhkan oleh system_error
model):
// 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 { };
}
Saya hanya memiliki sejumlah kecil situasi di mana saya melempar pengecualian yang diilustrasikan oleh enumerasi kode kesalahan.
Di atas tidak cocok dengan salah satu pengulas saya. Dia berpendapat bahwa saya seharusnya membuat hierarki kelas pengecualian dengan basis kelas yang berasal dari std::runtime_error
karena memiliki kode kesalahan tertanam dalam kondisi mencampur hal-hal - pengecualian dan kode kesalahan - dan itu akan lebih membosankan untuk berurusan dengan suatu titik penanganan; hierarki pengecualian juga akan memudahkan kustomisasi pesan kesalahan.
Salah satu argumen saya adalah bahwa saya ingin tetap sederhana, bahwa perpustakaan saya tidak perlu membuang beberapa jenis pengecualian dan kustomisasi juga mudah dalam hal ini seperti yang ditangani secara otomatis - yang error_code
telah menjadi error_category
terkait dengan itu yang menerjemahkan kode ke pesan kesalahan yang tepat.
Saya harus mengatakan bahwa saya tidak mempertahankan pilihan saya dengan baik, bukti fakta bahwa saya masih memiliki beberapa kesalahpahaman tentang pengecualian C ++.
Saya ingin tahu apakah desain saya masuk akal. Apa kelebihan metode lain dari yang saya pilih karena harus saya akui juga gagal melihatnya? Apa yang bisa saya lakukan untuk meningkatkan?