क्योंकि सी ++ स्थिर रूप से टाइप किया गया है, तो आपको एक ज्ञात प्रकार को पकड़ना होगा। हालांकि, आप बाहरी फ़ंक्शन (या फ़ंक्शंस सेट) को कॉल कर सकते हैं जो उस बिंदु पर अज्ञात अपवाद प्रकारों को संभालता है जिन्हें आप कॉल करते हैं। यदि इन हैंडलर सभी को ज्ञात प्रकार हैं, तो आप गतिशील रूप से प्रयास करने के लिए उन्हें पंजीकृत कर सकते हैं।
struct myStupidCustomString {
myStupidCustomString(char const *what) : what (what) {}
char const *what;
};
void throws() {
throw myStupidCustomString("here is some really useful information");
}
// The external library can provide a function, or you can provide a wrapper, which
// extracts information from "unknown" exception types.
std::string extract_from_unknown_external_exception() {
try { throw; }
catch (myStupidCustomString &e) {
return e.what;
}
catch (...) {
throw; // Rethrow original exception.
}
}
Use:
void example() {
try { throws(); }
catch (...) {
try {
std::string extracted = extract_from_unknown_external_exception();
std::cout << "extracted: " << extracted << '\n';
}
catch (...) {
// Chain handlers for other types; e.g. exception types from other libraries.
// Or do something generic for the unknown exception.
// Or rethrow the original unknown exception:
throw;
}
}
}
Handler chain:
typedef std::string Extract();
std::vector<Extract*> chain (1, &extract_from_unknown_external_exception);
// Chain would normally be initialized using whatever scheme you prefer for
// initializing global objects.
// A list or other container (including a manual linked list that doesn't
// require dynamic allocation) may be more appropriate, depending on how you
// want to register and unregister handlers.
std::string process_chain() {
for (std::vector<Extract*>::iterator x = chain.begin(); x != chain.end(); ++x) {
try {
return (*x)();
}
catch (...) {} // That handler couldn't handle it. Proceed to next.
}
throw; // None could handle it, rethrow original exception.
}
void example() {
try { throws(); }
catch (...) {
try {
std::string extracted = process_chain();
std::cout << "extracted: " << extracted << '\n';
}
catch (...) {
throw; // Rethrow unknown exception, or otherwise handle it.
}
}
}
अंत में, यदि आप कार्यान्वयन बारीकियों पता है, तुम उन को निकालने के लिए अपने कार्यान्वयन को उजागर करता है जो कुछ अतिरिक्त जानकारी का उपयोग कर सकते हैं। सी ++ 0 एक्स कुछ पोर्टेबल तरीके से कुछ विनिर्देशों का खुलासा करता है; std :: upgrade_ptr पर देखें।
स्रोत
2011-02-03 11:38:45
हाय, मुझे लगता है कि यह एक अच्छा जवाब है।हालांकि, मुझे इस मानक के बारे में मानक में कोई जानकारी नहीं मिल रही है कि यह मानक व्यवहार है या नहीं। मैंने इसका परीक्षण किया है, और यह विजुअलस्टूडियो, जीसीसी और एलएलवीएम दोनों में काम करता है, लेकिन मुझे पूरा यकीन नहीं है कि क्यों। तो एक नया 'प्रयास {} पकड़() {} 'ब्लॉक दर्ज करना वर्तमान अपवाद को किसी भी तरह से प्रभावित नहीं करता है? धन्यवाद! – NHDaly
मुझे लगता है कि मुझे यह भी यकीन नहीं है कि यह क्यों काम नहीं करेगा .. ऐसा लगता है कि एक कोशिश ब्लॉक में प्रवेश करने से कोई मौजूदा अपवाद प्रभावित नहीं होगा, लेकिन मुझे लगता है कि मैं सिर्फ दो बार जांच करना चाहता हूं। – NHDaly