0456c1fa3b1cd8d1a62e236fdbf86b80
Jeg kommer fra en Java-baggrund og er begyndt at arbejde med objekter i C++. Men en ting der slog mig er, at folk ofte bruger pointers til objekter i stedet for selve objekterne, f.eks. denne deklaration:



```
Object *myObject = new Object;
```

i stedet for:



```
Object myObject;
```

Eller i stedet for at bruge en funktion, lad os sige `testFunc()`, som her:



```
myObject.testFunc();
```

skal vi skrive:



```
myObject->testFunc();
```

Men jeg kan ikke finde ud af hvorfor vi skal gøre det på denne måde. Jeg vil antage at det har noget med effektivitet og hastighed at gøre, da vi får direkte adgang til hukommelsesadressen. Har jeg ret?


Hvorfor skal jeg bruge en pointer i stedet for selve objektet?
==============================================================


answer-id.com
2021.43
Det er meget uheldigt, at man så ofte ser dynamisk tildeling. Det viser bare, hvor mange dårlige C++-programmører der er.


På en måde har du to spørgsmål samlet i et. Det første er, hvornår skal vi bruge dynamisk allokering (ved hjælp af `new`)? Det andet er, hvornår vi skal bruge pointers?


Det vigtige budskab er, at man **altid skal bruge det rette værktøj til opgaven**. I næsten alle situationer er der noget mere hensigtsmæssigt og mere sikkert end at udføre manuel dynamisk allokering og/eller bruge rå pointere.


Dynamisk allokering
-------------------


I dit spørgsmål har du vist to måder at oprette et objekt på. Den største forskel er objektets opbevaringstid. Når du laver `Object myObject;` inden for en blok, oprettes objektet med automatisk lagringsvarighed, hvilket betyder, at det automatisk destrueres, når det går ud af rækkevidde. Når du laver `new Object()`, har objektet dynamisk opbevaringsvarighed, hvilket betyder, at det forbliver i live, indtil du udtrykkeligt `sletter` det. Du bør kun bruge dynamisk lagringsvarighed, når du har brug for det.
Det vil sige, **du bør *altid* foretrække at oprette objekter med automatisk lagringsvarighed, når du kan**.


De to vigtigste situationer, hvor du kan have brug for dynamisk allokering:


1. **Du har brug for, at objektet overlever det aktuelle anvendelsesområde** - det specifikke objekt på den specifikke hukommelsesplacering, ikke en kopi af det. Hvis du'er okay med at kopiere/flytte objektet (det bør du for det meste være), bør du foretrække et automatisk objekt.
2. **Du skal allokere en masse hukommelse**, hvilket let kan fylde stakken op. Det ville være rart, hvis vi ikke behøvede at bekymre os om dette (det meste af tiden bør du ikke behøve det), da det egentlig ligger uden for C++, men desværre må vi forholde os til virkeligheden i de systemer, vi udvikler til.


Når du absolut har brug for dynamisk allokering, bør du indkapsle den i en smart pointer eller en anden type, der udfører [RAII](https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) (som standardcontainere). Smart pointers giver ejerskabssemantik for dynamisk allokerede objekter. Se f.eks. på [`std::unique_ptr`](http://en.cppreference.com/w/cpp/memory/unique_ptr) og [`std::shared_ptr`](http://en.cppreference.com/w/cpp/memory/shared_ptr). Hvis du bruger dem hensigtsmæssigt, kan du næsten helt undgå at udføre din egen hukommelsesstyring (se [Rule of Zero](https://en.cppreference.com/w/cpp/language/rule_of_three)).


Pointere
--------


Der er dog andre mere generelle anvendelser af rå pointere ud over dynamisk allokering, men de fleste har alternativer, som du bør foretrække. Som tidligere **foretrækker du altid alternativerne, medmindre du virkelig har brug for pointers**.


1. **Du har brug for referencesemantik**. Nogle gange ønsker du at videregive et objekt ved hjælp af en pointer (uanset hvordan det blev allokeret), fordi du ønsker, at den funktion, som du videregiver det til, skal have adgang til det specifikke objekt (ikke en kopi af det). I de fleste situationer bør du dog foretrække referencetyper frem for pointere, fordi det er netop det, de er designet til. Bemærk, at dette ikke nødvendigvis handler om at forlænge objektets levetid ud over det aktuelle anvendelsesområde, som i situation 1 ovenfor. Som tidligere, hvis du har det fint med at videregive en kopi af objektet, har du ikke brug for referencesemantik.
2. **Du har brug for polymorphisme**. Du kan kun kalde funktioner polymorft (dvs. i henhold til et objekts dynamiske type) gennem en pointer eller reference til objektet. Hvis det'er den adfærd du har brug for, skal du bruge pointere eller referencer. Igen bør referencer være at foretrække.
3. **Du ønsker at repræsentere, at et objekt er valgfrit** ved at tillade, at der overgives en `nullptr`, når objektet udelades. Hvis det er et argument, bør du foretrække at bruge standardargumenter eller funktionsoverbelastninger. Ellers bør du helst bruge en type, der indkapsler denne adfærd, f.eks. `std::optional` (indført i C++17 - med tidligere C++-standarder skal du bruge `boost::optional`).
4. **Du ønsker at afkoble kompileringsenheder for at forbedre kompileringstiden**. Den nyttige egenskab ved en pointer er, at du kun har brug for en fremadrettet deklaration af den type, der peges på (for rent faktisk at bruge objektet har du brug for en definition). Dette giver dig mulighed for at afkoble dele af din kompileringsproces, hvilket kan forbedre kompileringstiden betydeligt. Se [Pimpl idiom] ([http://en.wikipedia.org/wiki/Opaque\_pointer](https://en.wikipedia.org/wiki/Opaque_pointer)).
5. **Du skal have en grænseflade med et C-bibliotek** eller et bibliotek i C-stil. På dette tidspunkt er du'tvunget til at bruge rå pointere. Det bedste du kan gøre er at sørge for, at du kun slipper dine raw pointers løs i sidste øjeblik. Du kan f.eks. få en rå pointer fra en smart pointer ved at bruge dens `get`-medlemsfunktion. Hvis et bibliotek udfører en allokering for dig, som det forventer, at du skal deallokere via et håndtag, kan du ofte pakke håndtaget ind i en smart pointer med en brugerdefineret deleter, der vil deallokere objektet på passende vis.

I C++ vil objekter, der allokeres på stakken (ved hjælp af `Object object;`-erklæringen i en blok), kun leve inden for det scope, de er deklareret i. Når kodeblokken er færdig med at udføre koden, destrueres det deklarerede objekt.
Hvis du allokerer hukommelse på heap ved hjælp af `Object* obj = new Object()`, fortsætter de med at leve i heap, indtil du kalder `delete obj`.


Jeg ville oprette et objekt på heap, når jeg gerne vil bruge objektet, ikke kun i den kodeblok, der har erklæret/allokeret det.


Lad os sige, at du har `klasse A`, der indeholder `klasse B` Når du ønsker at kalde en funktion i `klasse B` uden for `klasse A`, vil du blot få en pointer til denne klasse, og du kan gøre hvad du vil, og det vil også ændre konteksten for `klasse B` i din `klasse A`.


Men vær forsigtig med dynamiske objekter

