Disclaimer obbligatori
(1) Perché le persone che hanno visto il codice non possono dire nulla al riguardo e le persone che possono commentare liberamente non hanno mai visto il codice vero e proprio, tutto ciò che possiamo fare qui è di speculare, speculare e speculare. Pertanto, qui non è una risposta, solo una speculazione.
(2) Questo non è il modo tipico in cui scrivo C ++ perché la maggior parte dei progetti su cui lavoro consente eccezioni, almeno su base locale (cioè non oltre i limiti dell'applicazione), e lo standard di codifica garantisce che ci siano sempre catcher di eccezione appropriati nel posto giusto. Questa risposta è stata scritta come se fosse un pensiero interessante, non come una condivisione di esperienza.
La mia opinione è che per evitare il problema dell'oggetto parzialmente costruito (o, "stato"), è necessario innanzitutto modificare fondamentalmente il modo in cui viene eseguita la validazione dei parametri (precondizione) .
Il cambiamento è questo: invece di convalidare e assegnare i parametri uno per uno, si deve eseguire la convalida completa di tutti i parametri insieme, in modo da non avere effetti collaterali .
Oltre a questa modifica, viene modificato anche il ruolo del costruttore di classi. Invece di gestire sia la convalida della precondizione che l'inizializzazione dello stato, "esternalizzerà" entrambi a qualcun altro; manterrà solo la parte delle responsabilità che sono "failproof" (non in grado di fallire).
Ad esempio, l'assegnazione di un valore primitivo (ad esempio intero) a una variabile primitiva è a prova di errore, a condizione che la variabile primitiva abbia una memoria valida. Un altro esempio è il trasferimento di proprietà di un puntatore da una variabile intelligente a un'altra.
Alcuni dei più grandi progressi di C ++ 11 sono che i puntatori intelligenti (e molte altre cose) si stanno muovendo verso il rendere almeno alcune delle operazioni "a prova di errore", dando la possibilità di isolare quelle "disponibili" (avendo il potenziale di fallire) operazioni in metodi separati.
In definitiva, tuttavia, devo dire che la regola "nessuna eccezione" a volte è poco pratica per almeno alcuni tipi di sviluppo di applicazioni. In quale altro modo si impedisce std::bad_alloc
senza eccezioni? Dovrebbe il sistema crash-and-burn ?
I sistemi mission-critical prevengono i problemi di memoria esaurita garantendo un determinismo a livello di sistema nell'utilizzo della memoria. Tutto è preallocato; gli oggetti sono semplicemente placement-newed sugli allocatori. Esiste un numero massimo di istanze prescritte per ciascun tipo di oggetti; il tentativo di superare il massimo verrà rifiutato o provocherà lo yank di un altro oggetto meno importante, non attivamente in uso.
Questo potrebbe essere il motivo per cui continuiamo a sentire quei meme su "questo sistema di tracciamento nemico è in grado di tracciare simultaneamente 256 oggetti diversi". Quando un 257 ° oggetto vuole essere aggiunto al sistema, deve passare uno degli oggetti meno importanti. Dato che nessuno di noi commenta qui ha visto alcun codice, questa è solo una speculazione.