2014-09-10 11 views
6

Sono nuovo al C++ e sto provando a creare un'eccezione personalizzata che prende un messaggio nel suo codice.Come creare correttamente un'eccezione personalizzata con un messaggio?

Quello che ho in questo momento è questa:

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; 
}; 

Nel mio codice chiamante, ho questo come parte di un istruzioni switch (c è un char, o più specificamente, c = line[x]; dove x è un int e line è un std::string);

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

Il problema è che il mio Exception Ottiene una stringa completamente indipendenti (che è parte dello stesso metodo che genera: throw std::exception("There is more than 1 player start in the level.")).

Ho escluso un errore di logica - il mio programma raggiunge la riga in cui viene lanciata l'eccezione corretta con la stringa corretta. Quindi sono abbastanza sicuro che sia un problema di gestione della memoria/a vita.

A mio parere, C++ è il valore di copia per valore predefinito. Quindi ho pensato che chiamare il corriere di LevelLoadException avrebbe immediatamente copiato la stringa. Ma sembra che ci sia qualcosa di puntatore in corso, dal momento che la stringa che sto costruendo sembra una stringa C (const char*).

ho guardato la classe std::exception, e questo richiede un const char* const& come il messaggio e poi fa un po 'simile al C strcopy/malloc sotto il cofano (MSVC/Visual Studio 2012 Update 4).

Non sono sicuro al cento per cento di cosa ho realmente bisogno. Penso che quello che voglio sia una stringa che è incorporata nel chiamante, quindi spostata/copiata nell'eccezione (che ora possiede una copia della stringa di proprietà dell'eccezione) e poi quella nel chiamante viene distrutta quando è fuori scopo.

Qualcuno può darmi a pointer a quello che dovrei fare in modo diverso per farlo correttamente?

+0

E si cattura un'eccezione std? – Christophe

+0

@Christophe No, ho 'catch (LevelLoadException & e)' nel consumatore. –

+5

Si dovrebbe derivare da 'std :: runtime_error' invece di' std :: exception'. Quindi la tua lezione può essere ridotta a [un paio di righe] (http://coliru.stacked-crooked.com/a/9666bd1e13f8f25c). – Praetorian

risposta

12

"Invalid Character in Level: " + c non fa quello che pensi che faccia. Significa "un puntatore char* che viene compensato da N byte dall'inizio della stringa letterale", dove N è il codice ASCII del carattere memorizzato in c. Le probabilità sono alte, il letterale è in realtà inferiore a N caratteri, nel qual caso questo programma contiene un sovraccarico del buffer e presenta un comportamento non definito.

Make it

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

Ah, grazie. Quindi '' stringa ''restituisce un' char * '(per C retrocompatibile compat) e quindi sto facendo il pointer math (char c diventando il valore numerico 99)? Convertire la '' stringa ''in una stringa C++ usa l'' operatore + 'di' std :: string'? –

+0

@Praetorian: Ah, giusto. Farò la correzione, anche se non cambia radicalmente la risposta. –

+0

@MichaelStum: Hai capito (modulo '99' in realtà è il codice ASCII di qualsiasi carattere che si trova nella variabile' c', è stato un mio errore, mi dispiace per la confusione). –

Problemi correlati