2014-09-10 3 views
6

मैं सी ++ में नया हूं और मैं एक कस्टम अपवाद बनाने की कोशिश कर रहा हूं जो अपने सीटीआर में एक संदेश लेता है।संदेश के साथ एक कस्टम अपवाद कैसे ठीक से बनाया जाए?

यह क्या मैं अभी है:

class LevelLoadException : public std::exception 
{ 
public: 
    LevelLoadException(std::string msg) : m_message(msg) { } 
    const char * what() const throw() 
    { 
     return m_message.c_str(); 
    } 
private: 
    std::string m_message; 
}; 

मेरी बुला कोड में, मैं एक स्विच बयान का हिस्सा (c के रूप में इस एक चार, या अधिक विशेष रूप, c = line[x]; जहां x है एक int है और line एक std::string है);

default: 
    throw LevelLoadException("Invalid Character in Level: " + c); 

समस्या यह है कि मेरी अपवाद पूरी तरह से असंबद्ध स्ट्रिंग (: throw std::exception("There is more than 1 player start in the level.") है कि एक ही विधि है कि फेंकता का हिस्सा है) हो जाता है है।

मैंने एक तर्क बग को बाहर रखा है - मेरा प्रोग्राम उस रेखा तक पहुंचता है जहां सही स्ट्रिंग के साथ सही अपवाद फेंक दिया जाता है। तो मुझे पूरा यकीन है कि यह जीवन भर/स्मृति प्रबंधन समस्या है।

मेरी समझ के लिए, सी ++ डिफ़ॉल्ट रूप से कॉपी-बाय-वैल्यू है। तो मैंने सोचा कि LevelLoadException के सीटीओ को कॉल करने से तुरंत स्ट्रिंग की प्रतिलिपि होगी। लेकिन ऐसा लगता है कि कुछ पॉइंटर सामान चल रहा है, क्योंकि जिस स्ट्रिंग को मैं बना रहा हूं वह एक सी स्ट्रिंग (const char*) जैसा प्रतीत होता है।

मैं std::exception वर्ग को देखा है, और इस हुड (MSVC/विजुअल स्टूडियो 2012 अद्यतन 4) के तहत एक const char* const& संदेश के रूप में लेता है और फिर से करता है कुछ सी-तरह strcopy/malloc।

मैं सौ प्रतिशत निश्चित नहीं हूं कि मुझे वास्तव में क्या चाहिए। मुझे लगता है कि मैं जो चाहता हूं वह एक स्ट्रिंग है जिसे कॉलर में बनाया गया है, फिर अपवाद में स्थानांतरित/प्रतिलिपि बनाई गई है (जो अब स्ट्रिंग की एक प्रति है जो केवल अपवाद के स्वामित्व में है) और फिर कॉलर में से एक को नष्ट होने पर नष्ट कर दिया जाता है गुंजाइश।

क्या कोई मुझे a pointer दे सकता है कि मुझे यह सही तरीके से करने के लिए अलग-अलग क्या करना चाहिए?

+0

और आप एक एसटीडी अपवाद को पकड़ने? – Christophe

+0

@ क्रिस्टोफ़े नहीं, मेरे पास उपभोक्ता में 'कैच (लेवललोड अपवाद और ई) है। –

+5

आपको 'std :: upgrade' के बजाय' std :: runtime_error' से प्राप्त होना चाहिए। फिर आपकी कक्षा को [कुछ पंक्तियों] में घटाया जा सकता है (http://coliru.stacked-crooked.com/a/9666bd1e13f8f25c)। – Praetorian

उत्तर

12

"Invalid Character in Level: " + c ऐसा नहीं करता जो आपको लगता है कि ऐसा करता है। इसका मतलब है "एक char* सूचक जो स्ट्रिंग अक्षर की शुरुआत से N बाइट्स द्वारा ऑफ़सेट किया गया है", जहां Nc में संग्रहीत वर्ण का ASCII कोड है। संभावना अधिक है कि शाब्दिक वास्तव में N वर्णों से कम है, इस मामले में इस कार्यक्रम में एक बफर ओवररन होता है और अपरिभाषित व्यवहार प्रदर्शित करता है।

इसे

throw LevelLoadException(std::string("Invalid Character in Level: ") + c); 
+1

आह, धन्यवाद। तो '" स्ट्रिंग "' 'char *' (सी बैकवर्ड कॉम्पैट के लिए) देता है और फिर मैं पॉइंटर गणित कर रहा हूं (char c संख्यात्मक मान 99 बन रहा है)? '" स्ट्रिंग "को एक सी ++ स्ट्रिंग में कनवर्ट करना' std :: string' के 'ऑपरेटर +' का उपयोग करता है? –

+0

@Praetorian: आह, ठीक है। मैं सुधार कर दूंगा, हालांकि यह मूल रूप से उत्तर को बदल नहीं देता है। –

+0

@ माइकलस्टम: आपको यह मिला है (मॉड्यूलो 99 99 वास्तव में एएससीआईआई कोड है जो किसी भी चरित्र को चर 'c' में संग्रहीत किया जाता है; यह मेरी गलती थी, भ्रम के लिए खेद है)। –

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