C++ klasser

En klass i C++ är en användardefinierad typ eller datastruktur som deklareras med nyckelordsklass som har data och funktioner (även kallade medlemsvariabler och medlemsfunktioner ) som sina medlemmar vars åtkomst styrs av de tre åtkomstspecifikationerna privat , skyddad eller offentlig . Som standard är åtkomst till medlemmar i en C++-klass privat . De privata medlemmarna är inte tillgängliga utanför klassen; de kan endast nås genom klassens metoder. De offentliga medlemmarna bildar ett gränssnitt till klassen och är tillgängliga utanför klassen.

Förekomster av en klassdatatyp kallas objekt och kan innehålla medlemsvariabler, konstanter , medlemsfunktioner och överbelastade operatorer definierade av programmeraren.

Skillnader mellan en struktur och en klass i C++

I C++ har en klass som definieras med klassnyckelordet privata medlemmar och basklasser som standard . En struktur är en klass som definieras med nyckelordet struct . Dess medlemmar och basklasser är offentliga som standard. I praktiken är strukturer vanligtvis reserverade för data utan funktioner. När man härleder en struktur från en klass/struktur, är standardåtkomstspecifikationen för en basklass/struktur offentlig. Och när man härleder en klass är standardåtkomstspecifikationen privat.

Sammanlagda klasser

En aggregerad klass är en klass utan användardeklarerade konstruktörer, inga privata eller skyddade icke-statiska datamedlemmar, inga basklasser och inga virtuella funktioner. En sådan klass kan initieras med en klammerinnesluten kommaseparerad lista med initialiseringssatser. Följande kod har samma semantik i både C och C++.

  
   
   


  
    
   
   



    


       struct  C  {  int  a  ;  dubbel  b  ;  };  struct  D  {  int  a  ;  dubbel  b  ;  Cc  ;  _  };  // initiera ett objekt av typ C med en initieringslista  C  c  =  {  1  ,  2.0  };  // D har ett underaggregat av typ C. I sådana fall kan initialiseringssatser kapslas  D  d  =  {  10  ,  20.0  ,  {  1  ,  2.0  }}; 

POD-strukturer

En POD-struktur (Plain Old Data Structure) är en aggregerad klass som inte har några icke-statiska datamedlemmar av typen icke-POD-struktur, icke-POD-union (eller array av sådana typer) eller referens, och som inte har någon användar- definierad tilldelningsoperatör och ingen användardefinierad destruktor . En POD-struktur kan sägas vara C++-ekvivalenten till en C- struktur . I de flesta fall kommer en POD-struktur att ha samma minneslayout som en motsvarande struktur som deklareras i C. Av denna anledning brukar POD-strukturer ibland kallas "C-style structs".

Egenskaper delade mellan strukturer i C och POD-strukturer i C++

  • Datamedlemmar tilldelas så att senare medlemmar har högre adresser inom ett objekt, utom där de är åtskilda av en åtkomstspecificerare.
  • Två POD-strukturtyper är layoutkompatibla om de har samma antal ickestatiska datamedlemmar, och motsvarande ickestatiska datamedlemmar (i ordning) har layoutkompatibla typer.
  • En POD-struktur kan innehålla namnlös utfyllnad .
  • En pekare till ett POD-strukturobjekt, lämpligt konverterat med hjälp av en omtolkning av cast , pekar på dess initiala medlem och vice versa, vilket antyder att det inte finns någon utfyllnad i början av en POD-struktur.
  • En POD-struktur kan användas med makrot offset .

Deklaration och användning

C++-klasser har sina egna medlemmar. Dessa medlemmar inkluderar variabler (inklusive andra strukturer och klasser), funktioner (specifika identifierare eller överbelastade operatorer) kända som metoder, konstruktörer och destruktörer. Medlemmar förklaras vara antingen offentligt eller privat tillgängliga med hjälp av de offentliga: respektive privata : åtkomstspecifikationerna. Varje medlem som påträffas efter en specificator kommer att ha tillhörande åtkomst tills en annan specificator påträffas. Det finns också arv mellan klasser som kan använda sig av den skyddade: specificeraren.

Global och lokal klass

En klass definierad utanför alla metoder är en global klass eftersom dess objekt kan skapas var som helst i programmet. Om det är definierat inom en funktionskropp är det en lokal klass eftersom objekt i en sådan klass är lokala för funktionsomfånget.

Grunddeklaration och medlemsvariabler

Klasser deklareras med nyckelordet class eller struct . Medlemmarnas förklaring placeras i denna förklaring.

  

   
   
 struct  Person  {  strängnamn  ;  _  int  ålder  ;  }; 
  
 
   
   
 class  Person  {  public  :  strängnamn  ;  _  int  ålder  ;  }; 

Ovanstående definitioner är funktionellt likvärdiga. Båda koderna kommer att definiera objekt av typen Person som att ha två offentliga datamedlemmar, namn och ålder . Semikolon efter de avslutande klammerparenteserna är obligatoriska .

Efter en av dessa deklarationer (men inte båda), kan Person användas enligt följande för att skapa nydefinierade variabler av persondatatypen :

 
 

  
   
   


  
   
   
    
    
    
    
          
          
 #include  <iostream>  #include  <string>  struct  Person  {  std  ::  strängnamn  ;  _  int  ålder  ;  };  int  main  ()  {  Person  a  ;  Person  b  ;  a  .  name  =  "Calvin"  ;  b  .  name  =  "Hobbes"  ;  a  .  ålder  =  30  ;  b  .  ålder  =  20  ;  std  ::  cout  <<  a  .  namn  <<  ": "  <<  a  .  ålder  <<  std  ::  endl  ;  std  ::  cout  <<  b  .  namn  <<  ": "  <<  b  .  ålder  <<  std  ::  endl  ;  } 

Om du kör ovanstående kod matas ut

Calvin: 30 Hobbes: 20

Medlemsfunktioner

En viktig funktion i C++-klassen och -strukturen är medlemsfunktioner . Varje datatyp kan ha sina egna inbyggda funktioner (kallade metoder) som har tillgång till alla (offentliga och privata) medlemmar av datatypen. I kroppen av dessa icke-statiska medlemsfunktioner kan nyckelordet detta användas för att referera till objektet för vilket funktionen anropas. Detta implementeras vanligtvis genom att skicka objektets adress som ett implicit första argument till funktionen. persontypen ovan som ett exempel igen:

 

  
 
    

 
   
    


   
          
  
  
  
  
 #include  <iostream>  class  Person  {  public  :  void  Skriv ut  ()  const  ;  privat  :  std  ::  strängnamn_  ;  _  int  age_  =  5  ;  //C++ 11  };  void  Person::Print  ()  const  {  std  ::  cout  <<  name_  <<  ':'  <<  age_  <<  '\n'  ;  // "name_" och "age_" är medlemsvariablerna. Nyckelordet "detta" är ett   //-uttryck vars värde är adressen till objektet för vilket medlemmen  // anropades. Dess typ är "const Person*", eftersom funktionen deklareras   // const.  } 

I exemplet ovan deklareras Print -funktionen i klassens brödtext och definieras genom att kvalificera den med namnet på klassen följt av :: . Både name_ och age_ är privata (standard för klass) och Print deklareras som offentligt vilket är nödvändigt om det ska användas utanför klassen.

Med medlemsfunktionen Skriv ut kan utskriften förenklas till:


 a  .  Skriv ut  ();  b  .  Skriv ut  (); 

där a och b ovan kallas avsändare, och var och en av dem kommer att referera till sina egna medlemsvariabler när Print()- funktionen körs.

Det är vanligt att separera klass- eller strukturdeklarationen (kallas dess gränssnitt) och definitionen (kallas dess implementering) i separata enheter. Gränssnittet, som behövs av användaren, hålls i en header och implementeringen hålls separat i antingen käll- eller kompilerad form.

Arv

Layouten för icke-POD-klasser i minnet är inte specificerad av C++-standarden. Till exempel implementerar många populära C++-kompilatorer enstaka arv genom sammanlänkning av de överordnade klassfälten med de underordnade klassfälten, men detta krävs inte av standarden. Detta val av layout gör att referera till en härledd klass via en pekare till den överordnade klasstypen till en trivial operation.

Tänk till exempel

  
   
 struct  P  {  int  x  ;  }; 
    
   
 struktur  C  :  P  {  int  y  ;  }; 

En instans av P med en P* p som pekar på den kan se ut så här i minnet:

┏━━━━┓ ┃P::x┃ ┗━━━━┛ ↑ p

En instans av C med en P* p som pekar på den kan se ut så här:

┏━━━━┳━━━━┓ ┃P::x┃C::y┃ ┗━━━━┻━━━━┛ ↑ p

Därför kan vilken kod som helst som manipulerar fälten i ett P -objekt manipulera P -fälten inuti C -objektet utan att behöva överväga något om definitionen av C :s fält. Ett korrekt skrivet C++-program bör i alla fall inte göra några antaganden om layouten av ärvda fält. omvandlingsoperatorerna static_cast eller dynamic_cast kommer att säkerställa att pekare konverteras korrekt från en typ till en annan.

Multipelarv är inte lika enkelt. Om en klass D ärver P och C måste båda föräldrarnas fält lagras i någon ordning, men (högst) en av föräldraklasserna kan placeras längst fram i den härledda klassen. Närhelst kompilatorn behöver konvertera en pekare från D -typen till antingen P eller C , kommer kompilatorn att tillhandahålla en automatisk konvertering från adressen för den härledda klassen till adressen för basklassfälten (vanligtvis är detta en enkel offsetberäkning) .

För mer om multipelarv, se virtuellt arv .

Överbelastade operatörer

I C++ kan operatörer , såsom + - * / , överbelastas för att passa programmerares behov. Dessa operatörer kallas överbelastningsbara operatörer .

Enligt konvention bör överbelastade operatörer bete sig nästan likadant som de gör i inbyggda datatyper ( int , float , etc.), men detta krävs inte. Man kan deklarera en struktur som kallas Integer där variabeln verkligen lagrar ett heltal, men genom att anropa Integer * Integer kan summan, istället för produkten, av heltal returneras:

  
    
      

       
       
  

     0
 struct  Integer  {  Heltal  ()  =  default  ;  Heltal  (  int  j  )  :  i  {  j  }  {  }  Heltalsoperator  *  (  const  Heltal  &  k  )  const  {  returnera  Heltal  (  i  +  k  .  i  );  }  int  i  =  ;  }; 

Koden ovan använde en konstruktor för att "konstruera" returvärdet. För en tydligare presentation (även om detta kan minska programmets effektivitet om kompilatorn inte kan optimera satsen till motsvarande ovan), kan ovanstående kod skrivas om som:

     
   
      
   
 Heltalsoperator  *  (  const  Heltal  &  k  )  const  {  Heltal  m  ;  _  m  .  i  =  i  +  k  .  jag  ;  returnera  m  ;  } 

Programmerare kan också lägga in en prototyp av operatören i struct- deklarationen och definiera operatörens funktion i det globala omfånget:

  
    
      

      

     0

 
     
     
 struct  Integer  {  Heltal  ()  =  default  ;  Heltal  (  int  j  )  :  i  {  j  }  {  }  Heltalsoperator  *  (  const  Heltal  &  k  )  const  ;  int  i  =  ;  };  Heltal  Heltal  ::  operator  *  (  const  Heltal  &  k  )  const  {  returnera  Heltal  (  i  *  k  .  i  );  } 

i ovan representerar avsändarens egen medlemsvariabel, medan ki representerar medlemsvariabeln från argumentvariabeln k .

Nyckelordet const förekommer två gånger i ovanstående kod. Den första förekomsten, argumentet const heltal& k , indikerade att argumentvariabeln inte kommer att ändras av funktionen. Den andra förekomsten i slutet av deklarationen lovar kompilatorn att avsändaren inte skulle ändras av funktionskörningen.

I const heltal& k betyder et-tecken (&) "pass genom referens " . När funktionen anropas kommer en referens till variabeln att skickas till funktionen, snarare än värdet på variabeln.

Samma överbelastningsegenskaper ovan gäller även för klasser.

Observera att aritet , associativitet och prioritet för operatorer inte kan ändras.

Binära överbelastningsbara operatörer

Binära operatorer (operatorer med två argument) överbelastas genom att deklarera en funktion med en "identifierare" operator (något) som anropar ett enda argument. Variabeln till vänster om operatorn är avsändaren medan den till höger är argumentet.

    



   


     
     Heltal  i  =  1  ;  /* vi kan initiera en strukturvariabel på detta sätt som  om vi anropar en konstruktor med endast det första  argumentet specificerat. */   Heltal  j  =  3  ;  /* variabelnamn är oberoende av namnen på medlemsvariablerna  i strukturen. */   Heltal  k  =  i  *  j  ;  std  ::  cout  <<  k  .  i  <<  '\n'  ; 

'3' skulle skrivas ut.

Följande är en lista över binära överbelastningsbara operatorer:

Operatör Allmänt bruk
+ - * / % Aritmetisk beräkning
^ & ! << >> Bitvis uträkning
< > == != <= >= Logisk jämförelse
&& Logisk konjunktion
|| Logisk disjunktion
= <<= >>= Sammansatt uppdrag
, (ingen allmän användning)

Operatorn '=' (tilldelning) mellan två variabler av samma strukturtyp är som standard överbelastad för att kopiera hela innehållet i variablerna från en till en annan. Den kan skrivas över med något annat om det behövs.

Operatörer måste överbelastas en efter en, med andra ord är ingen överbelastning förknippad med varandra. Till exempel < inte nödvändigtvis motsatsen till > .

Ovanligt överbelastade operatörer

Medan vissa operatorer, som specificerats ovan, tar två termer, avsändare till vänster och argumentet till höger, har vissa operatorer bara ett argument - avsändaren, och de sägs vara "unära". Exempel är det negativa tecknet (när inget står till vänster om det) och det "logiska INTE " ( utropstecken , ! ).

Avsändaren av unära operatörer kan vara till vänster eller till höger om operatören. Följande är en lista över unär överbelastningsbara operatörer:

Operatör Allmänt bruk Avsändarens position
+ - Positivt/negativt tecken höger
* & Referens höger
! ~ Logisk / bitvis INTE höger
++ -- Föröka / minska höger
++ -- Efterökning/minskning vänster

Syntaxen för en överbelastning av en unär operator, där avsändaren är till höger, är följande:

return_type operator@ ()

När avsändaren är till vänster är deklarationen:

return_type operator@ (int)

@ ovan står för att operatören ska vara överbelastad. Ersätt return_type med datatypen för returvärdet ( int , bool , strukturer etc.)

Parametern int betyder i huvudsak ingenting annat än en konvention för att visa att avsändaren är till vänster om operatören.

const- argument kan läggas till i slutet av deklarationen om tillämpligt.

Överbelastningsfästen

Den fyrkantiga parentesen [] och den runda parentesen () kan överbelastas i C++-strukturer. Hakparentesen måste innehålla exakt ett argument, medan den runda parentesen kan innehålla valfritt antal argument, eller inga argument.

Följande deklaration överbelastar hakparentesen.

return_type operator[] ( argument )

Innehållet inom parentes anges i argumentdelen .

Runt fäste överbelastas på liknande sätt.

return_type operator() ( arg1, arg2, ... )

Innehållet i parentesen i operatörsanropet anges i den andra parentesen.

Förutom de operatorer som anges ovan kan piloperatorn ( -> ), den stjärnmärkta pilen ( ->* ), det nya nyckelordet och nyckelordet delete också överbelastas. Dessa minnes- eller pekarrelaterade operatörer måste bearbeta minnesallokeringsfunktioner efter överbelastning. Liksom tilldelningsoperatorn ( = ) är de också överbelastade som standard om ingen specifik deklaration görs.

Konstruktörer

Ibland kanske programmerare vill att deras variabler ska ta ett standardvärde eller specifikt värde vid deklaration. Detta kan göras genom att deklarera konstruktörer .

    
    
    
 Person  ::  Person  (  strängnamn  ,  int  ålder  )  {  name_  =  name  ;  _  age_  =  ålder  ;  } 

Medlemsvariabler kan initieras i en initialiseringslista, med användning av ett kolon, som i exemplet nedan. Detta skiljer sig från ovan genom att det initieras (med hjälp av konstruktorn), snarare än att använda tilldelningsoperatorn. Detta är mer effektivt för klasstyper, eftersom det bara behöver konstrueras direkt; medan med tilldelning måste de först initieras med standardkonstruktorn och sedan tilldelas ett annat värde. Vissa typer (som referenser och const -typer) kan inte heller tilldelas och måste därför initieras i initialiseringslistan.

        Person  (  std  ::  strängnamn  ,  int  ålder  )  :  name_  (  namn  ),  ålder_  (  ålder  )  {  } 

Observera att de lockiga hängslen inte kan utelämnas, även om de är tomma.

Standardvärden kan ges till de sista argumenten för att hjälpa till att initiera standardvärden.

       0     Person  (  std  ::  strängnamn  =  "  "  ,  int  ålder  =  )  :  name_  (  namn  ),  ålder_  (  ålder  )  {} 

När inga argument ges till konstruktorn i exemplet ovan, motsvarar det att anropa följande konstruktor utan argument (en standardkonstruktor):

   0  Person  ()  :  name_  (  ""  ),  age_  (  )  {} 

Deklarationen av en konstruktor ser ut som en funktion med samma namn som datatypen. Faktum är att ett anrop till en konstruktör kan ta formen av ett funktionsanrop. I så fall kan en initierad persontypvariabel ses som returvärdet:

  
      
  
 int  main  ()  {  Person  r  =  Person  (  "Wales"  ,  40  );  r  .  Skriv ut  ();  } 

En alternativ syntax som gör samma sak som exemplet ovan är

  
    
  
 int  main  ()  {  Person  r  (  "Wales"  ,  40  );  r  .  Skriv ut  ();  } 

Specifika programåtgärder, som kan eller inte kan relatera till variabeln, kan läggas till som en del av konstruktorn.

 
      
 Person  ()  {  std  ::  cout  <<  "Hej!"  <<  std  ::  endl  ;  } 

Med ovanstående konstruktör, ett "Hej!" kommer att skrivas ut när standardpersonkonstruktorn anropas .

Standardkonstruktör

Standardkonstruktörer anropas när konstruktörer inte är definierade för klasserna.

  
   


      

      

    struktur  A  {  int  b  ;  };  // Objekt skapat med parenteser.  A  *  a  =  nytt  A  ();  // Anropar standardkonstruktorn och b kommer att initialiseras med '0'.  // Objekt skapat utan parentes.  A  *  a  =  nytt  A  ;  // Allokera minne, anropa sedan standardkonstruktorn, och b kommer att ha värdet '0'.  // Objektskapande utan nytt.  A  a  ;  // Reservera plats för a på stacken, och b kommer att ha ett okänt skräpvärde. 

Men om en användardefinierad konstruktor definierades för klassen, kommer båda ovanstående deklarationer att anropa denna användardefinierade konstruktor, vars definierade kod kommer att exekveras, men inga standardvärden kommer att tilldelas variabeln b.

Förstörare

En destruktor är det omvända till en konstruktör. Den anropas när en instans av en klass förstörs, t.ex. när ett objekt av en klass skapat i ett block (uppsättning av krulliga klammerparenteser "{}") raderas efter den avslutande klammerparentesen, då anropas destruktorn automatiskt. Det kommer att anropas vid tömning av minnesplatsen som lagrar variablerna. Destruktorer kan användas för att frigöra resurser, såsom heap-allokerat minne och öppnade filer när en instans av den klassen förstörs.

Syntaxen för att deklarera en destruktor liknar den för en konstruktor. Det finns inget returvärde och namnet på metoden är detsamma som namnet på klassen med en tilde (~) framför.

 
            
 ~  Person  ()  {  std  ::  cout  <<  "Jag tar bort "  <<  namn_  <<  " med ålder "  <<  age_  <<  std  ::  endl  ;  } 

Likheter mellan konstruktörer och destruktörer

  • Båda har samma namn som klassen där de deklareras.
  • Om de inte deklareras av användaren är båda tillgängliga i en klass som standard, men de kan nu bara allokera och avallokera minne från objekten i en klass när ett objekt deklareras eller tas bort.
  • För en härledd klass: Under körtiden för basklasskonstruktorn har den härledda klasskonstruktorn ännu inte anropats; under körtiden för basklassförstöraren har den härledda klassförstöraren redan anropats. I båda fallen är de härledda klassmedlemsvariablerna i ett ogiltigt tillstånd.

Klass mallar

I C++ kan klassdeklarationer genereras från klassmallar. Sådana klassmallar representerar en familj av klasser. En faktisk klassdeklaration erhålls genom att instansiera mallen med ett eller flera mallargument. En mall instansierad med en viss uppsättning argument kallas en mallspecialisering.

Egenskaper

Syntaxen för C++ försöker få varje aspekt av en struktur att se ut som de grundläggande datatyperna . Därför tillåter överbelastade operatorer att strukturer kan manipuleras precis som heltal och flyttal, arrayer av strukturer kan deklareras med hakparentessyntaxen ( some_structure variable_name [size] ) , och pekare till strukturer kan avläsas på samma sätt som pekare till inbyggda datatyper.

Minnesförbrukning

Minnesförbrukningen för en struktur är åtminstone summan av minnesstorlekarna för ingående variabler. Ta TwoNums- strukturen nedan som ett exempel.

  
   
   
 struct  TwoNums  {  int  a  ;  int  b  ;  }; 

Strukturen består av två heltal. I många nuvarande C++-kompilatorer är heltal 32-bitars heltal som standard , så var och en av medlemsvariablerna förbrukar fyra byte minne. Hela strukturen förbrukar därför åtminstone (eller exakt) åtta byte minne, enligt följande.

+----+----+ | en | b | +----+----+

Dock kan kompilatorn lägga till utfyllnad mellan variablerna eller i slutet av strukturen för att säkerställa korrekt datajustering för en given datorarkitektur, ofta utfyllnadsvariabler för att vara 32-bitars justerade. Till exempel strukturen

   
   
   
   
    
   
   
 struct  BytesAndSuch  {  char  c  ;  kol  C  ;  kol  D  ;  kort  int  s  ;  int  i  ;  dubbel  d  ;  }; 

kunde se ut

+-+-+-+-+--+--+----+--------+ |c|C|D|X|s |XX| jag | d | +-+-+-+-+--+--+----+--------+

i minnet, där X representerar vadderade byte baserat på 4 byte justering.

Eftersom strukturer kan använda pekare och arrayer för att deklarera och initiera dess medlemsvariabler, är minnesförbrukningen för strukturer inte nödvändigtvis konstant . Ett annat exempel på icke-konstant minnesstorlek är mallstrukturer.

Bitfält

Bitfält används för att definiera de klassmedlemmar som kan uppta mindre lagringsutrymme än en integraltyp. Detta fält är endast tillämpligt för integraltyper (int, char, short, long, etc.) och exkluderar float eller double.

   
     
     
   0  
    
     
   
   
 struct  A  {  unsigned  a  :  2  ;  // Möjliga värden 0..3, upptar de första 2 bitarna av int  unsigned  b  :  3  ;  // Möjliga värden 0..7, upptar nästa 3 bitar av int  unsigned  :  ;  // Flyttar till slutet av nästa integraltyp  osignerad  c  :  2  ;  osignerad  :  4  ;  // Pads 4 bitar mellan c & d  osignerad  d  :  1  ;  osignerad  e  :  3  ;  }; 
  • Minnesstruktur
 4 byte int 4 byte int [1][2][3][4][5][6][7][8] [1] [2] [3] [4] [a][a] [b][b][b][ ][ ][ ] [ ][ ][ ][ ][ ][ ][ ][ ] [ ][ ][ ][ ][ ][ ][ ][ ] [ ][ ][ ][ ][ ][ ][ ][ ] [5] [6] [7] [8] [c][c][ ][ ][ ][ ][d][e] [e][e] ][ ][ ][ ][ ][ ][ ] [ ][ ][ ][ ][ ][ ][ ][ ] [ ][ ][ ][ ][ ][ ][ ][ ] 

Bitfält är inte tillåtna i en fackförening. Det är endast tillämpligt för de klasser som definieras med nyckelordet struct eller klass.

Passera genom referens

Många programmerare föredrar att använda et-tecken (&) för att deklarera argumenten för en funktion som involverar strukturer. Detta beror på att genom att använda dereferens-et-tecknet krävs endast ett ord (vanligtvis 4 byte på en 32-bitarsmaskin, 8 byte på en 64-bitarsmaskin) för att överföras till funktionen, nämligen minnesplatsen till variabeln. Annars, om pass-by-value används, måste argumentet kopieras varje gång funktionen anropas, vilket är kostsamt med stora strukturer.

Eftersom pass-by-reference exponerar den ursprungliga strukturen som ska modifieras av funktionen, bör nyckelordet const användas för att garantera att funktionen inte ändrar parametern (se const-correctness ), när detta inte är avsett.

Det här nyckelordet

För att underlätta strukturers förmåga att referera sig själva, implementerar C++ detta nyckelord för alla medlemsfunktioner. Detta nyckelord fungerar som en pekare till det aktuella objektet . Dess typ är en pekare till det aktuella objektet.

Detta nyckelord är särskilt viktigt för medlemsfunktioner med själva strukturen som returvärde :

    
    
    
   
 Complex  &  operator  +=  (  const  Complex  &  c  )  {  real_part_  +=  c  .  verklig_del_  ;  imag_part_  +=  c  .  bild_del_  ;  returnera  *  detta  ;  } 

Som nämnts ovan är detta en pekare, så användningen av asterisken (*) är nödvändig för att konvertera den till en referens som ska returneras.

Se även

Allmänna referenser: