2010-01-11 22 views
6

मैं कुछ प्रकार के अपवाद वर्ग में Win32 त्रुटियों (GetLastError() से लौटाए गए) को समाहित करना चाहता हूं। हालांकि, एक एकल Win32 अपवाद होने के बजाय, मैं सामान्य त्रुटियों, जैसे ERROR_ACCESS_DENIED के लिए एक विशेष अपवाद को पकड़ने में सक्षम होना चाहता हूं।सी ++ अपवाद डिजाइन पैटर्न

उदाहरण के लिए, मैं इस तरह की कक्षाओं घोषित होगा:

class WindowsException : public std::exception 
{ 
public: 
    static WindowsException Create(DWORD lastError); 
    //blah 

}; 

class ErrorAccessDeniedException : public WindowsException 
{ 
public: 
    //blah 
}; 

हालांकि, मैं चाहूँगा Win32 अपवाद वापस जाने के लिए सही अपवाद उठा लिए जिम्मेदार होने की। यही कारण है, अपवाद के फेंकने तरह दिखना चाहिए:

int DangerousMethod() { 
    throw WindowsAPI::WindowsException::Create(GetLastError()); 
} 

और पकड़ने वाला लग सकता है जैसे: तो

try 
{ 
    DangerousMethod(); 
} catch(WindowsAPI::ErrorAccessDeniedException ex) 
{ 
    //Code for handling ERROR_ACCESS_DENIED 
} catch(WindowsAPI::WindowsException ex) 
{ 
    //Code for handling other kinds of error cases. 
} 

मेरे समस्या यह है कि अगर WindowsException :: कारखाने पद्धति बनाएं रिटर्न एक WindowsException है, उप प्रकार (संभावित रूप से ErrorAccessDeniedException) को आधार प्रकार पर काटा जाता है। यही है, उदाहरण polymorphic नहीं हो सकता है। मैं एक नए पॉइंटर का उपयोग नहीं करना चाहता, क्योंकि यह अपवाद हैंडलर को पूरा होने पर इसे हटाने के लिए मजबूर करेगा।

क्या किसी को डिज़ाइन समाधान के बारे में पता है जो इस समस्या को हल करने के लिए संभव होगा?

Billy3

+0

आप कुछ अलग अपवाद प्रकार घोषित करने के लिए एक मैक्रो बना सकते हैं, और 'GetLastError() 'के मूल्य के आधार पर फेंकने के लिए एक कारखाना बना सकते हैं; लेकिन ईमानदार होने के लिए, मैंने कभी इस समस्या को इस तरह से देखा है: http://code.google.com/p/synergy-plus/source/browse/trunk/lib/arch/XArchWindows.cpp –

+0

समस्या वह समाधान यह है कि यह आपको विशिष्ट पकड़ हैंडलर बनाने की अनुमति नहीं देता है - यह उस प्रकार के सभी अपवादों के लिए एक अपवाद प्रकार है। –

+1

आपको अपने अपवादों को संदर्भ से संदर्भित करना चाहिए, मूल्य के अनुसार नहीं, क्योंकि आपका उपरोक्त कोड नमूना वर्तमान में –

उत्तर

12

बदलें

int DangerousMethod() { 
    throw WindowsAPI::WindowsException::Create(GetLastError()); 
} 

करने के लिए

int DangerousMethod() { 
    WindowsAPI::WindowsException::Throw(GetLastError()); 
} 

अर्थ, बजाय अपवाद लौटने तो यह फेंक (जो, स्लाइस, जैसा कि आप देखा) की, अपने सहायक/कारखाना है विधि इसे सीधे फेंक दें।

+1

... दुह बिल :) बहुत बहुत धन्यवाद। –

+2

जैसा कि मैं सवाल पढ़ रहा था, मैं एक ठोस समाधान का आविष्कार कर रहा था जहां ढांचे द्वारा हर संभव अपवाद का एक स्थिर उदाहरण बनाए रखा गया था। एक बार जब आप इसे देख चुके हैं तो टेरी का समाधान केवल "डीयूएच स्पष्ट" है। (या तो वह, या हम दोनों बेवकूफ हैं :-) –

+1

'WindowsAPI :: WindowsException :: थ्रो()' के साथ क्या गलत है और उस फ़ंक्शन कॉल को 'GetLastError()' दे रहा है? – sbi

2

कुछ और अपवाद हैंडलिंग पृष्ठभूमि पढ़ने: http://www.informit.com/articles/article.aspx?p=373339

प्रकार टुकड़ा करने की क्रिया और rethrowing पर एक नोट:

जब एक अपवाद ई rethrowing, सिर्फ लेखन पसंद करते हैं फेंक; फेंक ई के बजाय ; क्योंकि पहला फॉर्म हमेशा रीथ्राउन ऑब्जेक्ट के बहुरूपता को संरक्षित करता है।

+2

यह नहीं कह रहा कि यह बुरी जानकारी है, लेकिन ... मेरे प्रश्न के साथ उसे क्या करना है? –

+0

बस अपवाद हैंडलिंग के साथ अधिक संभावित टुकड़े करने के मुद्दों को सतर्क करना। –

संबंधित मुद्दे