Gettando provvisori non const per riferimento
-
20-09-2019 - |
Domanda
C'è qualche problema con gettando un oggetto costruito sullo stack in un try-block con riferimento non-const, la cattura e la modifica, poi gettandolo dal riferimento a un altro blocco catch?
Di seguito è riportato un breve esempio di quello che sto riferendosi a.
struct EC {
EC(string msg) { what = msg; }
string where;
string what;
void app(string& t) { where += t; }
string get() { return what; }
};
try {
try {
try {
EC error("Test");
throw error;
}
catch (EC& e) {
e.app("1");
throw e;
}
}
catch (EC& e) {
e.app("2");
throw e;
}
}
catch (EC& e) {
e.app("3");
cout << e.where << endl;
cout << e.get() << endl;
}
E 'possibile che questo potrebbe causare e.what per contenere spazzatura, ma e.where di rimanere intatto? Per esempio:
e.where è "123"
e.get () restituisce un sacco di dati spazzatura, fino a quando non accade a colpire un byte nullo.
Soluzione
Non esiste una cosa come "lancio per riferimento". E 'semplicemente impossibile. Non c'è sintassi per questo. Ogni volta che si tenta di "buttare un riferimento", una copia dell'oggetto di riferimento è in realtà gettato. Inutile dire che non ci sono tentativi di gettare per riferimento nel codice.
E 'possibile cattura un'eccezione precedentemente lanciata da riferimento (anche da un non-const) e modificare l'oggetto eccezione temporaneo attraverso di essa. Funzionerà. In realtà, è possibile ri-lanciare l'ormai modificato esistente oggetto eccezione invece di creare un nuovo uno. Cioè si può solo fare
throw;
anziché
throw e;
nelle clausole catch e ancora ottenere il codice correttamente comportarsi, vale a dire l'oggetto originale (con modifiche) continuerà il suo volo throgh la gerarchia gestore.
Tuttavia, il codice è mal formate presso il
e.app("1");
chiamata (e altre chiamate a app
) poiché il parametro di riferimento non-const. Modificare la dichiarazione app
a uno
void app(const string& t) { where += t; } // <- either this
void app(string t) { where += t; } // <- or this
per la sua compilazione.
In caso contrario, il codice dovrebbe funzionare bene. Non sono tenuti a ottenere qualsiasi spazzatura da get()
. Se lo fai, deve essere o un problema con il compilatore o con il tuo codice che non si mostra.