मैं एक छोटी सी लाइब्रेरी को कोड कर रहा हूं और मुझे अपवाद हैंडलिंग को डिजाइन करने में थोड़ी परेशानी हो रही है। मुझे कहना होगा कि मैं C ++ भाषा की इस विशेषता से भ्रमित (अभी भी) हूं और मैंने इस विषय पर यथासंभव पढ़ने की कोशिश की कि मुझे अपवाद कक्षाओं के साथ ठीक से काम करने के लिए क्या करना होगा।
मैंने कक्षा system_error
के एसटीएल कार्यान्वयन से प्रेरणा लेते हुए एक प्रकार के दृष्टिकोण का उपयोग करने का निर्णय लिया 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 ++ अपवादों के बारे में कुछ गलतफहमी है।
मैं जानना चाहूंगा कि क्या मेरा डिजाइन समझ में आता है। मैंने जिस पद्धति को चुना है, उस पर अन्य पद्धति के क्या फायदे होंगे क्योंकि मुझे यह स्वीकार करना होगा कि मैं भी इसे देखने में असफल हूं? मैं क्या सुधार कर सकता था?