2015-12-22 3 views
7

Le eccezioni sono una grande parte del C++ e uno dei motivi per usarlo (so che ci sono molti, più importanti, altri motivi) è di evitare inutili controlli che offuscano il codice con un sacco di dichiarazioni if (forse questo è un errore assunzione?).Perché lo std :: shared_ptr dereference non genera un'eccezione di puntatore nullo (o simile)?

Quindi ora sono curioso di sapere perché std::shared_ptr::operator* e std::shared_ptr::operator-> non gettare un null_ptr_exception o simile?

+0

Hai trovato l'implementazione di un puntatore intelligente che fa il comportamento descritto ? – aggsol

+0

@aggsol, no, abbiamo finito per crearne di nostri utilizzando le politiche di implementazione e modello esistenti – Samaursa

risposta

7

La mia comprensione è che le classi di puntatore intelligente sono progettate per apparire e comportarsi come puntatori grezzi. Dato questo principio guida del design, il codice idealmente legacy potrebbe semplicemente sostituire l'uso di puntatori raw con puntatori intelligenti usando semantica di proprietà equivalente e il codice funzionerebbe esattamente come prima.

Pertanto, la modifica del comportamento per il dereferenziamento di puntatori intelligenti non dovrebbe eseguire verifiche aggiuntive o generare eccezioni (ad esempio, poiché i puntatori grezzi non si comportano in questo modo).

La proposta di aggiungere puntatori intelligenti allo standard indica questa decisione di progettazione (A Proposal to Add General Purpose Smart Pointers to the Library Technical Report):

III. Le decisioni di progettazione

Principi

A. generali

  1. "Come vicino a Raw Puntatori possibile, ma non più vicino"
+1

Grazie per la risposta. Devo ammettere che la ragione del comitato dello standard non è soddisfacente.Se sostituiamo il codice legacy con puntatori intelligenti, allora un 'null_ptr_exception' non sarà gestito e il programma si interromperà comunque (proprio come un'asserzione, sebbene concessa senza lo srotolamento - quindi, ancora una volta, proprio come un'affermazione, questa eccezione può essere suddivisa in da un debugger). – Samaursa

+1

@Samaursa Per un puntatore raw che dereferenzia un puntatore nullo attiva il comportamento non definito e il programma può sembrare funzionare perfettamente normalmente, ma comprendo il tuo punto di vista e la tua frustrazione. –

4

Se è stato richiesto ogni dereferenziamento di un puntatore condiviso per verificare l'esistenza di nullptr e generare un'eccezione, potrebbero esserci molti controlli ridondanti, codice gonfiato e sovraccarico. Certo, l'ottimizzatore è in grado di eliminare un po 'di tutto ciò, ma ancora ... Invece, il programmatore dovrebbe controllare una volta prima, tuttavia, molte dereferenze.

+0

Ma non è questo l'argomento per/contro le eccezioni/i codici di errore? – Samaursa

+1

@Samaursa: no ... il dereferenziamento di un puntatore non elaborato o del puntatore intelligente della Libreria standard è consentito generare un codice macchina che presuppone che il puntatore non sarà mai nullptr - il codice macchina verrà eseguito più rapidamente del codice che deve controllare ed evitare (per lo stesso casi non nullptr) ramificati al codice di gestione degli errori. La mancata verifica/ramificazione è più veloce, indipendentemente dal fatto che tale gestione venga raggiunta utilizzando un'eccezione o un codice di errore (che a loro volta può variare in termini di velocità e dimensioni del codice macchina). –

+0

Mi aspetterei che 'unique_ptr' abbia un'asserzione e' shared_ptr' (dato che è già un oggetto piuttosto pesante con il conteggio dei riferimenti e il tracking 'weak_ptr's) a' throw'. Tuttavia, ha senso come un puntatore. La dereferenziazione è un'operazione estremamente comune. – Samaursa