2012-04-05 13 views
7

मैं अपवाद कक्षाओं में auto_ptr के साथ एक समस्या है नहीं हो सकता है कि मैं अंत में करने के लिए कम:क्यों मैं एक अपवाद वर्ग में एक auto_ptr

/perforce/unstable/test/Common/Exceptions/TestException4.cpp: In function 'int main()': /perforce/unstable/test/Common/Exceptions/TestException4.cpp:12: error: no matching function for call to 'MyException::MyException(MyException)' /perforce/unstable/test/Common/Exceptions/TestException4.cpp:4: note: candidates are: MyException::MyException() /perforce/unstable/test/Common/Exceptions/TestException4.cpp:4: note: MyException::MyException(MyException&) /perforce/unstable/test/Common/Exceptions/TestException4.cpp:12: error: in thrown expression

:

#include <memory> 

class MyException 
{ 
    std::auto_ptr<int> m_foo2; 
}; 

int main() 
{ 
    try 
    { 
     throw MyException(); 
    } 
    catch (const MyException&) 
    { 

    } 
    return 0; 
} 

इस के साथ संकलित करने के लिए विफल रहता है

और अगर मैं auto_ptr को हटा देता हूं तो त्रुटि दूर हो जाती है।

क्या ऐसा इसलिए है क्योंकि अपवाद की प्रतिलिपि बनाई जा रही है या असाइन की जा रही है? क्या अपवाद में auto_ptr एस का उपयोग करने का कोई तरीका है?

+0

वाह, उच्च गुणवत्ता वाले उत्तरों यहां। एक अच्छा सवाल होना चाहिए। :) – sje397

उत्तर

9

Is this because the exception is being copied or assigned?

वास्तव में यह है। मानक निर्दिष्ट करता है कि एक अपवाद में फेंक दिया जाता है सी ++ 11 15.1/3:

A throw-expression initializes a temporary object, [...]. The temporary is an lvalue and is used to initialize the variable named in the matching handler.

initialisation निहित प्रतिलिपि निर्माता के साथ किया जाता है। इसे MyException(MyException&) के रूप में घोषित किया गया है, क्योंकि ऐसे सदस्य हैं जिनके लिए एक गैर-const संदर्भ तर्क (जैसा कि C++ 11 12.8/9 में निर्दिष्ट है) की आवश्यकता होती है। अस्थायी वस्तु को गैर-const संदर्भ से बाध्य नहीं किया जा सकता है, और इसलिए निर्माण विफल हो जाता है।

Is there a way of using auto_ptrs in an Exception?

आप सी ++ 11 का उपयोग कर सकें, तो आप unique_ptr बजाय इस्तेमाल कर सकते हैं, और इतिहास की आंत को auto_ptr सुपुर्द। आपकी कक्षा में एक अंतर्निहित चालक कन्स्ट्रक्टर होगा, जिसे MyException(MyException&&) के रूप में घोषित किया गया है, जिसका उपयोग अस्थायी से शुरू करने के लिए किया जा सकता है।

अन्यथा, आप एक गैर अस्थायी मूल्य फेंक सकता है:

MyException ex; 
throw ex; 

या आप एक स्पष्ट प्रतिलिपि निर्माता जोड़ने और const_cast या mutable का उपयोग कर कि करने के लिए अनुमति देने के लिए द्वारा एक const संदर्भ से initialisation अनुमति देने के लिए अपनी कक्षा हैक कर सकता है auto_ptr कॉपी करें - लेकिन यह संभावित रूप से खतरनाक है, और मैं इसकी अनुशंसा नहीं करता।

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