2013-10-31 26 views
5

Guardando il codice legacy ho trovato qualcosa di simile al seguente codiceoverloading degli operatori nuovi ed eccezione correttezza

void* legacy_type::operator new(size_t size) { 
    return pool_alloc(size); 
} 

pool_alloc è noto per non gettare e restituire 0 in caso di guasto.

Non c'è sovraccarico per la variante std :: nothrow di new qui.

Mi chiedo se questo codice sia semanticamente corretto e abbia un comportamento ben definito.

In caso di new (std::nothrow) legacy_type; utilizzare pool_alloc personalizzato? Nel mio compilatore non si compila affatto. È un comportamento ben definito?

Se il costruttore si avvia e si blocca a causa di this==0 se sovraccarico operator new restituisce zero? Nel mio compilatore funziona (e si blocca durante l'inizializzazione del membro). È un comportamento standard ben definito?

+0

Il costruttore non deve essere chiamato se "operatore new" restituisce un puntatore nullo e quindi l'intera espressione "new" restituirà un puntatore nullo. – Simple

+0

È comportamento accettabile in C++, ma si bloccherà se la classe ha un tavolo virtuale o un costruttore che non prova 'questo == 0 'prima di accedere membri variabili. Ovviamente non è usuale e probabilmente dovrebbe essere evitato. Si può cercare di eliminare solo quella definizione e vedere cosa succede ... –

risposta

1

1) No, non dovrebbe. Queste sono diverse funzioni. E, quando si sovraccarica una delle operazioni - tutte le altre operazioni non funzionerà mai, se non sono sovraccarichi, dato che se non v'è operator new in classe-portata e la firma non è accettabile, allora compilatore non cercare per il mondiale operator new, così, la compilazione -error sarà successo.

2) si interrompe postcondizioni, se il vostro new tornerà puntatore nullo. n3376 18.6.1.1/3

Comportamento richiesto: restituire un puntatore non nullo alla memoria adeguatamente allineata (3.7.4), oppure lanciare un'eccezione di allocazione male_- alloc. Questo requisito è vincolante per una versione sostitutiva di questa funzione.

Se si vuole restituisce 0, è necessario utilizzare seguente firma

void* operator new(size_t) throw() 

se si utilizza questo sovraccarico e ritorna 0 da esso, non v'è alcun seg-colpa.

n3376 5.3.4/13

Se la funzione assegnazione restituisce null, inizializzazione non sarà fatto, la funzione deallocazione non sarà chiamato, e il valore della nuova espressione deve essere nullo.

+0

vedo, "non nullo" è esplicitamente dichiarato nella norma, grazie. – Muxecoid