Küçük bir kütüphaneyi kodluyorum ve istisna yönetimini tasarlamakta sorun yaşıyorum. C ++ dilinin bu özelliğiyle (hala) kafam karıştığımı söylemeliyim ve istisna sınıflarıyla düzgün çalışmak için ne yapmam gerektiğini anlamak için konuyla ilgili mümkün olduğunca fazla okumaya çalıştım.
Sınıfın system_error
STL uygulamasından ilham alan bir tür yaklaşım kullanmaya karar verdim future_error
.
Hata kodlarını içeren bir numaralandırma var:
enum class my_errc : int
{
error_x = 100,
error_z = 101,
error_y = 102
};
ve tek bir istisna sınıfı (bir error_category
tür yapı ve system_error
modelin ihtiyaç duyduğu her şey tarafından desteklenir ):
// 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 { };
}
Hata kodu numaralandırması ile gösterilen istisnaları attığım durumlar çok az.
Yukarıdaki benim yorumculardan biri ile iyi oturmadı. Durumunda std::runtime_error
gömülü hata kodunun bazı şeyleri - istisnaları ve hata kodlarını - karıştırması nedeniyle türetilmiş bir temel sınıf ile bir istisna sınıfı hiyerarşisi oluşturmam gerektiğine inanıyordu ve bir noktayla uğraşmak daha sıkıcı olurdu elleçleme; kural dışı durum hiyerarşisi hata mesajının kolayca özelleştirilmesini de sağlar.
Benim argümanlardan biri Kütüphanemin istisnalar birden fazla türde atmak gerek olmadığını, basit tutmak istedim oldu ve otomatik olarak işlenir olarak özelleştirme bu durumda kolay da olduğu - error_code
bir etti error_category
çevirir o onunla ilişkili uygun hata iletisini kodlayın.
C ++ istisnaları ile ilgili hala bazı yanlış anlaşılmalara sahip olduğumun kanıtı, seçimimi iyi bir şekilde savunmadım.
Tasarımımın mantıklı olup olmadığını bilmek istiyorum. Bunu da göremediğimi itiraf etmem gerektiğinden, diğer yöntemin seçtiğim yöntemden avantajları ne olurdu? Geliştirmek için ne yapabilirim?