कस्टम अपवादों के मामले में अतिरिक्त विवरण के लिए यहां बताए गए अन्य उत्तरों के लिए ADD से संबंधित है ।
उस मामले में जहां आप अपने स्वयं के कस्टम अपवाद बनाते हैं, जो व्युत्पन्न होता है std::exception
, जब आप "सभी संभव" अपवाद प्रकारों को पकड़ते हैं, तो आपको हमेशा catch
"सबसे व्युत्पन्न" अपवाद प्रकार के साथ क्लॉस शुरू करना चाहिए जो पकड़ा जा सकता है। उदाहरण देखें (क्या नहीं करना है):
#include <iostream>
#include <string>
using namespace std;
class MyException : public exception
{
public:
MyException(const string& msg) : m_msg(msg)
{
cout << "MyException::MyException - set m_msg to:" << m_msg << endl;
}
~MyException()
{
cout << "MyException::~MyException" << endl;
}
virtual const char* what() const throw ()
{
cout << "MyException - what" << endl;
return m_msg.c_str();
}
const string m_msg;
};
void throwDerivedException()
{
cout << "throwDerivedException - thrown a derived exception" << endl;
string execptionMessage("MyException thrown");
throw (MyException(execptionMessage));
}
void illustrateDerivedExceptionCatch()
{
cout << "illustrateDerivedExceptionsCatch - start" << endl;
try
{
throwDerivedException();
}
catch (const exception& e)
{
cout << "illustrateDerivedExceptionsCatch - caught an std::exception, e.what:" << e.what() << endl;
// some additional code due to the fact that std::exception was thrown...
}
catch(const MyException& e)
{
cout << "illustrateDerivedExceptionsCatch - caught an MyException, e.what::" << e.what() << endl;
// some additional code due to the fact that MyException was thrown...
}
cout << "illustrateDerivedExceptionsCatch - end" << endl;
}
int main(int argc, char** argv)
{
cout << "main - start" << endl;
illustrateDerivedExceptionCatch();
cout << "main - end" << endl;
return 0;
}
ध्यान दें:
०) उचित क्रम इसके विपरीत होना चाहिए, अर्थात- पहले आप catch (const MyException& e)
जो इसके बाद हैं catch (const std::exception& e)
।
1) जैसा कि आप देख सकते हैं, जब आप प्रोग्राम को चलाते हैं, तो पहले कैच क्लॉज़ को निष्पादित किया जाएगा (जो कि शायद वही है जो आप पहले स्थान पर नहीं चाहते थे)।
2) भले ही पहला कैच क्लॉज में पकड़ा गया प्रकार हो std::exception
, लेकिन "उचित" संस्करण को what()
कहा जाएगा - क्योंकि यह संदर्भ द्वारा पकड़ा गया है (कम से कम पकड़े गए तर्क std::exception
प्रकार को मूल्य के आधार पर बदलें - और आप अनुभव करेंगे "ऑब्जेक्ट स्लाइसिंग" क्रिया में घटना)।
3) इस मामले में कि "XXX कोड को फेंके जाने के तथ्य के कारण कुछ कोड ..." अपवाद के प्रकार के साथ महत्वपूर्ण सामान करता है, यहां आपके कोड का दुर्व्यवहार है।
4) यह भी प्रासंगिक है यदि पकड़े गए ऑब्जेक्ट "सामान्य" वस्तु जैसे: class Base{};
और class Derived : public Base {}
...
5) g++ 7.3.0
उबंटू 18.04.1 पर एक चेतावनी है जो उल्लिखित मुद्दे को इंगित करती है:
फ़ंक्शन में 'शून्य चित्रणड्रेडएक्सडैप्शनकैच ()': item12Linux.cpp: 48: 2: चेतावनी: 'MyException' प्रकार के अपवाद को पकड़ा जाएगा (const MyException & e) ^ ~~~~
item12Linux.cpp: 43: 2: चेतावनी: 'std :: अपवाद' के लिए पहले हैंडलर द्वारा
(कास्ट अपवाद और e) ^ ~~~~
फिर से , मैं कहूंगा कि यह उत्तर केवल ADD से यहां वर्णित अन्य उत्तरों के लिए है (मुझे लगा कि यह बिंदु ध्यान देने योग्य है, फिर भी इसे एक टिप्पणी के भीतर चित्रित नहीं किया जा सकता है)।