2010-09-27 11 views
17

Wikipedia stati:È ancora possibile allocare esplicitamente C++ 0x all'operatore globale?

Un tipo può essere fatto impossibile allocare con operatore nuovo:

struct NonNewable { 
    void *operator new(std::size_t) = delete; 
}; 

Un oggetto di questo tipo può essere solo assegnato come oggetto pila o come membro di un'altra genere. Non può essere assegnato direttamente all'heap senza trucchi non portatili. (Poiché nuova collocazione è l'unico modo per chiamare un costruttore sulla memoria utente-allocata e questo uso è stato proibito come sopra, l'oggetto non può essere costruito in modo corretto.)

eliminazione operatore nuovo è simile a renderlo privata C++ corrente, ma non utilizza esplicitamente l'operatore globale new, che evita la ricerca specifica della classe, C++ 0x ancora valido?

NonNewable *p = ::new NonNewable(); 
// neither non-portable nor trickery, though perhaps not widely known 

Ho perso qualcosa nella bozza?


Per essere chiari, questo è valido C++ 03 e works fine:

struct NonNewable { 
private: 
    void *operator new(std::size_t); // not defined 
}; 

int main() { 
    // ignore the leaks, it's just an example 

    void *mem = operator new(sizeof(NonNewable)); 
    NonNewable *p = ::new(mem) NonNewable(); 

    p = ::new NonNewable(); 

    return 0; 
} 
+1

FYI se stai verificando: il testo citato è stato cancellato dall'articolo di Wikipedia. –

risposta

6

Credo che lei abbia ragione e wikipedia è sbagliato. Lo standard di bozza C++ 0x descrive "funzioni cancellate" (8.4p10) come funzioni che non possono essere utilizzate in alcun modo (oppure il programma è mal formato). Non hanno alcun ruolo nella ricerca dell'ambito o del nome rispetto alle normali funzioni. E i paragrafi relativi alle nuove espressioni sono rimasti gli stessi:

[5.3.4p8] Una nuova espressione ottiene la memorizzazione per l'oggetto chiamando una funzione di allocazione (3.7.4.1). ...

[5.3.4p9] Se la nuova espressione inizia con un operatore unario ::, il nome della funzione di allocazione viene cercato nell'ambito globale. Altrimenti, se il tipo allocato è un tipo di classe T o un array di esso, il nome della funzione di allocazione viene cercato nell'ambito di T. Se questa ricerca non riesce a trovare il nome, o se il tipo assegnato non è un tipo di classe, l'allocazione il nome della funzione è ricercato nell'ambito globale.

Quindi sì, l'espressione ::new NonNewable [o ::new(mem) NonNewable] avrebbe scelto un sovraccarico di ::operator new, ignorando la funzione NonNewable::operator new, e non avrebbe fatto il programma di mal-formata.