2012-05-28 7 views
5

In C++, se una classe ha un membro dati di riferimento, l'operatore di assegnazione predefinito non viene sintetizzato dal compilatore. Perché?Perché un operatore di assegnazione predefinito non viene sintetizzato dal compilatore se una classe ha un membro dati di riferimento

+0

In che modo verrà inizializzato tale riferimento? – Mat

+9

Non è possibile _reassign_ un riferimento. Assegnare semplicemente modificherebbe l'oggetto di riferimento, che potrebbe non essere quello che vuoi. –

risposta

6

In C++, se una classe ha un elemento di dati di riferimento l'operatore di assegnazione predefinito non è sintetizzato da compilatore. Perché?

Che assegnamento per copia dovrebbe fare è definita in:

C++ 03 standard 12.8/13:

Ogni sotto-oggetto viene assegnato in modo appropriato per il tipo:

  • se il sotto-oggetto è di tipo di classe, l'operatore di assegnazione copia per la classe è usato (come se per qualifica esplicita; cioè, ignorando qualsiasi possibile funzione di override virtuale in più classi derivate);

  • se il sottooggetto è una matrice, ogni elemento è assegnato, nel modo appropriato al tipo di elemento;

  • se il sottooggetto è di tipo scalare, viene utilizzato l'operatore di assegnazione incorporato.

In breve implica che ogni dell'organo dovrebbe assegnato in modo adeguato
che solleva la questione,
Quale dovrebbe essere il comportamento per l'assegnazione di un organo di riferimento in classe?
Si consideri il seguente sui riferimenti:

  1. I riferimenti sono intrinsecamente non assegnabili, continuano a riferimento lo stesso referrant a cui sono stati inizializzati [Ref 1].
  2. In virtù di #1 l'assegnazione a un riferimento non riassegna il riferimento, modifica il valore del referrant che è un comportamento non intuitivo.

Non v'è alcun comportamento corretto di default deve essere eseguita qui, ma piuttosto una situazione one.So mandati C++ standard che progettista della classe è in posizione migliore per determinare questo comportamento e da qui la decisione che operatore di assegnazione di default non dovrebbe essere sintetizzato dal compilatore se una classe ha un membro di dati di riferimento.

Questa decisione è specificato in:
C++ 03 standard 12.8/12:

Un operatore di assegnamento per copia implicitamente dichiarata è implicitamente definito quando un oggetto di questo tipo di classe è assegnato un valore del suo tipo di classe o un valore di un tipo di classe derivato dal suo tipo di classe. Un programma è mal formata se la classe per la quale un operatore di assegnamento per copia è implicitamente definito ha:
.......
- un membro di dati non statico di tipo di riferimento, o
.......


[Ref 1]
C++ 03 standard 8.5.3/2:

Un riferimento non può essere modificato per fare riferimento a un altro oggetto dopo l'inizializzazione. Si noti che l'inizializzazione di un riferimento viene trattata in modo molto diverso dall'assegnazione ad esso. L'argomento passing (5.2.2) e function value return (6.6.3) sono inizializzazioni.

3

Ha visto la discussione in un forum di soli membri. Poiché la risposta non è ben nota alla maggior parte dei programmatori, vorrebbe pubblicare la risposta e condividerla qui.

Da C++ progetto di norma N3337 §12.8.23:

Una copia/spostamento operatore di assegnazione stabilizzato per la classe X è definito come eliminato se X ha:

  • dell'utente variante con un non -trivial corrispondente operatore di assegnazione e X è una classe unione-simili, o
  • un membro di dati non statica di const tipo non-classe (o matrice di esso), o
  • un non-stati c membro di riferimento del tipo di riferimento o
  • un membro di dati non statici di classe tipo M (o matrice dello stesso) che non può essere copiato/spostato perché risoluzione di sovraccarico (13.3), come applicato all'operatore di assegnazione corrispondente di M corrispondente in un'ambiguità o una funzione eliminata o inaccessibile dall'operatore di assegnazione predefinito o
  • una classe di base diretta o virtuale B che non può essere copiata/spostata perché risoluzione sovraccarico (13.3), applicata all'operatore di assegnazione corrispondente di B , restituisce un'ambiguità o una funzione che viene cancellata o inaccessibile dall'operatore di assegnazione predefinito o
  • per l'operatore di assegnazione spostamento, un membro dati non statico o classe base diretta con un tipo che non ha un operatore di assegnazione spostamento e non è banalmente copiabile o qualsiasi classe di base virtuale diretta o indiretta.
+1

È fantastico che tu abbia postato una citazione dallo standard, ma è più importante capire il * motivo *: che l'operatore di assegnazione dovrebbe assegnare al membro di riferimento dell'oggetto LHS un nuovo valore, ma i riferimenti non possono essere assegnato (sono implicitamente costanti). – HighCommander4

Problemi correlati