2013-09-04 13 views
10

Perché l'argomento del costruttore di copie è un riferimento anziché un puntatore?Perché l'argomento del costruttore di copie è un riferimento anziché un puntatore?

Perché non è possibile utilizzare il puntatore?

+1

è possibile scrivere un puntatore costruttore 'Foo Foo :: (Foo const *) ', ma non è un costruttore _copy_. Dato 'Foo a;' una costruzione di copia ha l'aspetto di 'Foo b (a);' oppure 'Foo c = a;' (e in C++ 11 forse 'Foo d {a};'). Ora considera 'Foo x (&a);' o 'Foo y = & a;', sembra un _copy_ per te? .. –

risposta

13

Ci sono molte ragioni:

  1. I riferimenti non possono essere NULL. OK, è possibile creare un riferimento NULL, ma è anche possibile trasmettere un std::vector<int>* in un std::vector<SomeType>*. Ciò non significa che un simile cast abbia definito un comportamento. E nemmeno crea un riferimento NULL. I puntatori hanno un comportamento definito se impostati su NULL; i riferimenti non lo fanno. Pertanto, i riferimenti si riferiscono sempre agli oggetti reali.

  2. Le variabili e i provvisori non possono essere convertiti implicitamente in puntatori ai loro tipi. Per ovvie ragioni. Non vogliamo che i puntatori ai temporaries girino, ed è per questo che lo standard vieta espressamente di farlo (almeno quando il compilatore può dire che lo state facendo). Ma a noi è permesso avere riferimenti; questi sono creati implicitamente.

  3. A causa del punto numero 2, usando puntatori piuttosto che riferimenti richiederebbe ogni operazione di copia di utilizzare l'operatore di indirizzo (&). Oh aspetta, il comitato del C++ ha scioccamente permesso che fosse sovraccaricato. Quindi qualsiasi operazione di copia dovrebbe effettivamente utilizzare std::addressof, una caratteristica di C++ 11, per ottenere l'indirizzo. Quindi ogni copia dovrebbe apparire come Type t{std::addressof(v)}; Oppure potresti semplicemente usare riferimenti.

1

Perché un puntatore può essere un nullptr che deve essere controllato e ai provvisori non possono essere assegnati dei puntatori.

5

Perché questo è negato dallo standard.

Citando ++ progetto n3376 C standard - sezione 12.8.2:

Un costruttore non template per la classe X è un costruttore di copia se il suo primo parametro è di tipo X &, const X &, volatili X & o const X volatili &, e uno non ci sono altri parametri, altrimenti tutti gli altri parametri hanno argomenti di default

8

È solo nomenclatura. Puoi anche usare un puntatore, ma sarebbe chiamato costruttore di conversioni .

Se ci pensate, ha senso, perché copiate un oggetto in un altro (ergo la "copia"). Non da un puntatore a un oggetto. Se era un puntatore, non farebbe una copia, perché non stai copiando il puntatore all'oggetto, ma piuttosto l'oggetto puntato dal puntatore al tuo oggetto.

+2

'È solo nomenclatura' - Non sono d'accordo. Se hai un costruttore di conversioni - copia costruttore Sarà definito implicitamente, che può essere diverso da quello che vuoi. – ForEveR

+1

@ForEveR è ancora nomenclatura però. Non avere il termine stesso avrebbe reso più prolisso, certo, ma non impossibile –

+0

Sarebbe la nomenclatura se entrambi fossero nomi estranei per costruttori che accettano vari parametri, ma questo non è il caso in cui 'copy constructor' è uno dei tre grandi: se non definisci un' costruttore di conversione' come lo chiami qualcuno che tenta di usarlo probabilmente otterrà un errore del compilatore (potrebbe dipendere se si usa 'explicit' o no), dove verrà creato un costruttore di copia per loro che potrebbe essere diverso dal' costruttore di conversione'. Per non parlare della maggior parte delle funzioni o classi STL o basate su modelli l'interazione si aspetta che il 'copy constructor' funzioni correttamente. – UpAndAdam

5

Perché dovrebbe essere un puntatore? Un puntatore nullo non avrebbe senso. E l'utilizzo di un puntatore non consentirebbe la copia temporanei, in modo da non si poteva fare le cose come:

MyClass 
func() 
{ 
    // ... 
    return MyClass(...); 
} 

È possibile definire un costruttore di prendere un puntatore. Ma non sarà essere un costruttore di copia, perché non potrebbe essere utilizzato in casi come sopra. E non impedirà al compilatore di generare un costruttore di copie.

1

Passando da riferimenti assicura un oggetto reale è passato al costruttore di copia, mentre un puntatore può avere un valore NULL, e rendere sicuro il costruttore

Problemi correlati