2011-12-26 5 views
5

Supponiamo di avere una classe che non supporta la copia membro, quindi non voglio preservare il costruttore di copia e l'operatore di assegnazione implementati dal compilatore. Anche io non voglio implementare quelli perché oDoes "operator =" restituisce type matter se voglio rendere la classe non-copyable?

  1. così facendo prende sforzo in più e non ho bisogno di tali operazioni nella mia classe o
  2. quelle operazioni non ha senso nella mia classe

quindi voglio vietarli. Per farlo I'll declare them private and provide no implementation:

class NonCopyable { 
private: 
    NonCopyable(const NonCopyable&); //not implemented anywhere 
    void operator=(const NonCopyable&); //not implemented anywhere 
}; 

ora posso selezionare qualsiasi tipo di ritorno per operator=() funzione membro. Importerà quale tipo di ritorno seleziono?

+2

Nota anche che con C++ 11 puoi renderlo ancora più chiaro facendo 'void operator = (const NonCopyable &) = delete;' –

risposta

1

conta una minuscola bit:

  • void assicura una piccola percentuale di chiamate accidentali/sbagliate (a = b = c/f (d = e)) dall'interno implementazione della classe produrre compilare errori di tempo piuttosto che errori di link time, che potrebbero far risparmiare tempo alla compilazione ed essere più comprensibili (minimamente rilevanti per le grandi classi toccate da molti sviluppatori, alcuni con familiarità precedente limitata).

  • void sarebbe suonare un campanello d'allarme per me (e, si spera la maggior parte degli sviluppatori), chiedendosi se:

    • voluto rimuovere il default-generato operator=
    • erano solo pigro circa la digitazione in più, o
    • non erano familiari/non curanti della semantica generalmente prevista di operator=.

Con la questione aperta in mente, altri programmatori hanno meno probabilità di venire avanti e pensare basta non andare in giro a fornire l'attuazione e inserirlo con indifferenza (si i commenti potrebbero essere adeguati).

  • restituire un riferimento al tipo può rendere la firma funzione generale più istantaneamente riconoscibile, o la ricerca visivamente passato un tipo complicato trovare operator= potrebbe avere l'effetto opposto - tutto negli occhi (e mente) dell'osservatore ....
+0

+1, no pensa agli errori di compilazione del tempo vs tempo di collegamento –

2

No, dal momento che non chiamerai mai questo operatore nel tuo codice. Tendo a mantenere il tipo di ritorno NonCopyable &, per chiarezza e coerenza.

7

No, il tipo di reso non ha importanza.

Lo standard C++ non impone alcun requisito per il tipo di reso per le funzioni membro speciale di assegnazione copia che si dichiara. Deve solo essere un operator=() che accetti "esattamente un parametro di tipo X, X&, const X&, volatile X& o const volatile X&". †† Pertanto, void operator=(const NonCopyable&); è ancora un operatore di assegnazione copia (uno specificato dall'utente, per essere specifico).

Poiché in effetti è stato fornito il proprio operatore di assegnazione delle copie, verrà annullata la generazione dell'operatore di assegnazione delle copie predefinito. Ciò impone tutte le chiamate all'operatore di assegnazione delle copie di NonCopyable da risolvere sul proprio, provocando l'impossibilità di compilare i tentativi di utilizzare l'operatore di assegnazione delle copie dal momento che è stato dichiarato private.

class Foo : NonCopyable 
{ 
}; 

int main() 
{ 
    Foo a; 
    Foo b; 
    // Compiler complains about `operator=(const NonCopyable&)` 
    // not accessible or something like that. 
    a = b; 
} 

E siccome non sarò mai in grado di utilizzare in realtà, non importa che non è esattamente l'operatore di assegnamento per copia canonica. Se provassi ad usare l'operatore di assegnazione delle copie, si tradurrebbe in un errore del compilatore, che è esattamente quello che vuoi.


† Naturalmente, non importa, stilisticamente parlando, se l'operatore di assegnazione copia in realtà fa qualcosa. In genere si desidera che gli operatori si comportino esattamente come quelli incorporati, pertanto restituire uno X& è una buona pratica quando si esegue effettivamente l'assegnazione.

†† C++ standard: oggetti 12.8 classe Copia [class.copy]

Un utente-dichiarato copia assegnazione operatore X::operator= è una funzione membro non-modello di non-statico classe X con esattamente un parametro di tipo X, X&, const X&, volatile X& o const volatile X&.

1

No, perché è possibile restituire qualsiasi valore da operator=, anche se si definisce la sua implementazione.

1

No, non importa, dal momento che non si implementa mai un'istruzione return. Se si tenta di richiamare l'operatore, il compilatore non sarà in grado di trovare un'implementazione (con qualsiasi tiporeturn, quindi il tipo restituito è irrilevante).

È interessante notare che l'operatore di assegnazione copia boost::noncopyable è dichiarato restituire un const noncopyable&, ma suppongo che sia solo una convenzione.

Problemi correlati