2010-04-29 16 views
5

Sono riuscito a superare la mia carriera di programmatore di giochi C++ fino ad ora praticamente senza mai toccare eccezioni, ma di recente ho lavorato a un progetto con il motore Ogre e sto cercando di apprendere correttamente. Ho trovato molte buone domande e risposte qui sull'uso generale delle eccezioni C++, ma mi piacerebbe ottenere alcune opinioni da qui in poi su se l'uso di Ogre è buono e su come lavorare al meglio con loro.L'uso di Eccezioni da parte di Ogre è un buon modo per usarle?

Per cominciare, citando la documentazione di Ogre di essa la propria classe Exception:

OGRE non usa mai i valori di ritorno per indicare gli errori. Invece, se si verifica un errore, viene generata un'eccezione e questo è l'oggetto che incapsula il dettaglio del problema. L'applicazione che utilizza OGRE dovrebbe sempre garantire che le eccezioni vengano intercettate, quindi tutte le funzioni del motore OGRE dovrebbero verificarsi all'interno di un blocco try {} catch (Ogre :: Exception & e) {}.

Davvero? Ogni singola funzione Ogre può generare un'eccezione e essere racchiusa in un blocco try/catch? Al momento questo viene gestito nel nostro utilizzo da un try/catch in main che mostrerà una finestra di messaggio con la descrizione dell'eccezione prima di uscire. Questo può essere un po 'imbarazzante per il debug anche se non si ottiene una traccia di stack, solo la funzione che ha generato l'errore - più importante è la funzione del nostro codice che ha chiamato la funzione Ogre. Se fosse un assert in codice Ogre, passerebbe direttamente al codice nel debugger e sarei in grado di scoprire cosa sta succedendo molto più facile - non so se mi manchi qualcosa che mi permetterebbe di debug di eccezioni già?

Sto iniziando ad aggiungere altri blocchi try/catch nel nostro codice ora, generalmente pensando se è importante se la funzione Ogre genera un'eccezione. Se è qualcosa che fermerà tutto ciò che funziona, lascia che sia il try/catch principale a gestirlo e ad uscire dal programma. Se non è di grande importanza, prendilo subito dopo la chiamata della funzione e lascia che il programma continui. Un recente esempio di questo è stato la costruzione di un vettore dei parametri del programma vertice/frammento per i materiali applicati a un'entità - se un materiale non aveva parametri allora genererebbe un'eccezione, che ho catturato e poi ignorato come non ha fatto t necessario aggiungere al mio elenco di parametri. Questo sembra un modo ragionevole di affrontare le cose? Un consiglio specifico per lavorare con Ogre è molto apprezzato.

risposta

19

Non è necessario avvolgere tutte le ultime chiamate su Ogre in try { ... } catch. Lo fai ovunque tu possa gestire in modo significativo l'eccezione. In alcuni casi questo potrebbe essere nel sito di chiamata individuale o potrebbe essere in un loop di alto livello di qualche tipo. Se non riesci a gestirlo in modo significativo da nessuna parte, non afferrarlo affatto; lascia che il debugger prenda il sopravvento.

In particolare, non si devono rilevare eccezioni in main() per il motivo preciso che si cita (almeno, non durante lo sviluppo, si dovrebbe in produzione).

+6

+1 per "Ovunque sia possibile gestire in modo significativo l'eccezione" – Yacoby

+0

Pertanto, l'eccezione si applicherebbe in modo significativo all'eccezione relativa al mio ultimo esempio di ricerca di parametri? Finché nulla è stato modificato prima dell'eccezione, non causerà alcun problema. il giorno scorsa ha indicato come eseguire il debug delle eccezioni quando vengono lanciate, il che sarà di grande aiuto, se togli il try/catch principale in modalità debug cosa succederà se non vengono rilevate eccezioni? – identitycrisisuk

+0

Quando le eccezioni non vengono rilevate, il debugger lo rileva e mostra il punto da cui è stato generato. – Christopher

6

Non so nulla di Ogre, temo, ma la regola generale con la gestione delle eccezioni è che si cattura l'eccezione il più lontano possibile dal sito di lancio, ma non oltre. Tuttavia, ciò è possibile solo se il codice che genera l'eccezione utilizza RAII per controllare le risorse allocate. Se il codice utilizza l'allocazione dinamica per puntatori semplici o altre forme di gestione manuale delle risorse, è necessario provare i blocchi sul sito di chiamata. Se questo è il caso, direi che l'uso delle eccezioni è una cattiva idea.

+0

Penso che Ogre sia per lo più ok da un punto di vista per l'allocazione delle risorse, la maggior parte utilizza la propria classe del puntatore condivisa (che non consiglia di riutilizzare però ...) e si può lasciare a ripulire una volta che non si utilizza più roba. – identitycrisisuk

6

Sembra che tu non sappia come eseguire il debug delle eccezioni. O

  • Portare il/Eccezioni dialogo VS Debug e spuntare la C++ eccezioni scatola.Questo ti darà un'opportunità (appare una finestra di dialogo) per eseguire il debug quando viene lanciata un'eccezione .

o

  • Se avete costruito fonte Ogre, impostare un punto di interruzione nel costruttore Ogre::Exception e quando tenta di buttare quello che si romperà con uno stack di chiamate in cui il livello successivo è il sito di lancio.
+0

Grazie mille, sapevo che ci sarebbe stato qualcosa ma non riuscivo a trovarlo. Avrei dovuto pensare anche al breakpoint del costruttore. – identitycrisisuk