Tilldelningsoperatör (C++)
I programmeringsspråket C++ är tilldelningsoperatorn =
den operator som används för tilldelningen . Som de flesta andra operatörer i C++ kan den överbelastas .
Kopieringsuppdragsoperatören , ofta bara kallad "uppdragsoperatören", är ett specialfall av tilldelningsoperatör där källan (höger sida) och destination (vänster sida) är av samma klasstyp . Det är en av de speciella medlemsfunktionerna , vilket innebär att en standardversion av den genereras automatiskt av kompilatorn om programmeraren inte deklarerar en. Standardversionen utför en medlemsvis kopia, där varje medlem kopieras av sin egen operatör för kopieringstilldelning (som också kan vara programmerardeklarerad eller kompilatorgenererad).
Kopieringstilldelningsoperatorn skiljer sig från kopieringskonstruktören genom att den måste rensa upp datamedlemmarna i uppdragets mål (och korrekt hantera självtilldelning) medan kopieringskonstruktorn tilldelar värden till oinitierade datamedlemmar. Till exempel:
My_Array först ; // initiering av standardkonstruktorn My_Array andra ( första ); // initiering av kopieringskonstruktorn My_Array tredje = första ; // Också initiering av kopia konstruktorn andra = tredje ; // uppdrag av kopia uppdrag operatör
Returvärde för överbelastad uppdragsoperatör
Språket tillåter en överbelastad tilldelningsoperatör att ha en godtycklig returtyp (inklusive void
). Operatören definieras dock vanligtvis för att returnera en referens till mottagaren. Detta överensstämmer med beteendet hos tilldelningsoperatören för inbyggda typer ( retursätter det tilldelade värdet ) och gör det möjligt att använda operatoranropet som ett uttryck, till exempel i kontrollsatser eller i kedjad tilldelning . Dessutom C++ Standard Library detta beteende för vissa typer av användare.
Överbelastad kopia uppdrag operatör
När djupa kopior av föremål måste göras bör undantagssäkerhet beaktas. Ett sätt att uppnå detta när resursallokeringen aldrig misslyckas är:
- Skaffa nya resurser
- Släpp gamla resurser
- Tilldela de nya resursernas handtag till objektet
class My_Array { int * array ; int count ; public : My_Array & operator = ( const My_Array & other ) { if ( this != & other ) { // skydda mot ogiltig självtilldelning // 1: allokera nytt minne och kopiera elementen int * new_array = new int [ other . räkna ]; std :: copy ( annan . array , annan . array + annan . count , new_array ); // 2: avallokera gammalt minne radera [ ] array ; // 3: tilldela det nya minnet till objektmatrisen = new_array ; räkna = annat . räkna ; } // enligt konvention, returnera alltid *this return * this ; } // ... };
Men om en no-fail ( no-throw ) swap -funktion är tillgänglig för alla medlemssubobjekt och klassen tillhandahåller en kopiakonstruktor och destruktor (vilket den ska göra enligt regeln om tre ), det enklaste sättet att implementera kopia uppdraget är som följer:
public : void swap ( My_Array & other ) // funktionen swap member (bör aldrig misslyckas!) { // swap alla medlemmar (och bassubobjekt, om tillämpligt) med andra med hjälp av std :: swap ; // på grund av ADL kommer kompilatorn att använda // anpassat swap för medlemmar om det finns // faller tillbaka till std::swap swap ( array , other . array ); byta ( räkna , annat . räkna ); } My_Array & operator = ( My_Array other ) // notera: argument passerat av värde! { // swap this with other swap ( other ); // enligt konvention, returnera alltid *this return * this ; // annat förstörs, släpper minnet }
Uppdrag mellan olika klasser
C++ stöder tilldelning mellan olika klasser, både via implicit kopieringskonstruktor och tilldelningsoperator, om destinationsinstansklassen är förfadern till källinstansklassen:
class Ancestor { public : int a ; }; klass Descendant : public Ancestor { public : int b ; }; int main () { Descendant d ; Anfader a ( d ); Anfader b ( d ); a = d ; }
Kopiering från förfader till efterkommande objekt, som kan lämna efterkommandes fält oinitierade, är inte tillåtet.
Se även
externa länkar
- The Anatomy of the Assignment Operator , av Richard Gillam