2016-10-08 4 views
-1
sf::RectangleShape* operator()() 
{ 
    return &player; 

} // RectangleShape Getter 

Muss ich Speicher nach diesem Getter freigeben? Wenn ja, wie würde man das mit unique_ptr machen?Make Pointer Getter verwenden unique_ptr

versuchte ich

std::unique_ptr<sf::RectangleShape> operator()() 
{ 
    return std::unique_ptr<sf::RectangleShape>(player); 

} // RectangleShape Getter 

Aber es sagt, dass es für die Klammer Operator keine passende Funktion ist. Wie sonst sollte das gemacht werden?

+0

Ein eindeutiger Zeiger muss entweder von "make_unique" zurückgegeben werden oder anderweitig aus dem Wert eines "new" -Ausdrucks erstellt werden. –

+4

Was ist 'Spieler'? – Galik

+0

'player' scheint kein Zeiger zu sein, da du seine Adresse im ersten Beispiel nimmst – krzaq

Antwort

0
sf::RectangleShape* operator()() 
{ 
    return &player; 

} // RectangleShape Getter 

Do I need to free memory after this getter?

Alles, was Sie tun, ist ein Zeiger auf player zurückzukehren. Angenommen, dies ist eine Membervariable der Struktur/Klasse, zu der die obige Elementfunktion gehört, dann ist ihre Lebensdauer an die Lebensdauer des Objekts gebunden, mit dem Sie diese Funktion aufrufen.

Insbesondere bedeutet dies, dass dies eine schlechte Idee ist:

std::unique_ptr<sf::RectangleShape> operator()() { 
    return make_unique<sf::RectangleShape>(player); 
} 

Die Kopie:

struct Foo { 
    sf::RectangleShape player; 
    // ... 
    // insert your operator here 
}; 

sf::RectangleShape * some_function(void) { 
    Foo f; 
    return f(); // UB, returning pointer to object with automatic memory whose lifetime has ended 
} 

[..] how would one do this with unique_ptr?

sf::RectangleShape eine Kopie Konstruktor Unter der Annahme, dann könnte man eine Kopie player machen Du bekommst den Weg "dein", dh du kannst dein Leben so gestalten, wie du es willst.

+0

Also, wenn ich make_unique verwende, macht es eine Kopie oder ist es das gleiche Objekt mit den gleichen Eigenschaften? – kim366

+0

Es ist eine Kopie. Natürlich unter der Annahme, dass Objekte dieses Typs tatsächlich * kopiert werden können *. –

+0

Okay, so dass diese Methode nicht praktikabel ist, da es dasselbe Objekt sein muss. Vielen Dank! – kim366

1

Es scheint wie player Mitglied einer Klasse ist und Sie versuchen, einen Zeiger darauf zu verteilen, damit es außerhalb der Klasse geändert wird?

In diesem Fall besitzt die Klasse, zu der sie gehört, den Speicher, und es liegt an dieser Klasse, die Daten freizugeben, wenn sie zerstört werden. Ein Zeiger auf dieses Member sollte absolut nicht außerhalb der Klasse freigegeben werden.

Es würde helfen, mehr Informationen über die besitzende Klasse zu haben, aber wenn ich annehmen kann, dass player ein Datenmitglied ist, dann ist Ihr erstes Beispiel technisch in Ordnung. Es ist jedoch oft idiomatischer, eine Referenz als Zeiger zurückzugeben.

Wenn die obige Annahme falsch ist, sollten Sie Ihre vollständige Klassendefinition anzeigen, damit wir mehr Informationen haben, um eine korrekte Lösung zu bilden.

+0

Ihre Annahme ist korrekt und der einzige Grund, warum ich einen Zeiger über eine Referenz verwende, ist, dass es außerhalb der Klasse klarer ist, dass es keine Kopie ist, sondern tatsächlich die Elementvariable und dass sie sorgfältig behandelt werden sollte. Soweit ich es jetzt herausgefunden habe, müssen Sie sich nur um die Speicherverwaltung kümmern, wenn Sie eine Zeigervariable erstellen oder das Schlüsselwort 'new' verwenden. Ist das korrekt? – kim366

+1

Sie sollten sich Gedanken darüber machen, Speicher freizugeben, wenn eine dynamische Speicherzuordnung z. Verwenden von 'new' oder einer der C-style' alloc'-Varianten. Diese werden normalerweise verwendet, wenn eine Ressource innerhalb einer Funktion erstellt und von einer Funktion zurückgegeben wird oder das Objekt zu groß ist, um direkt auf dem Stapel zugeordnet zu werden. In diesen Fällen ist es oft besser, ein "unique_ptr" (über die Funktion 'make_unique') zu erstellen, da die Ressource dann automatisch bereinigt wird, wenn ptr den Gültigkeitsbereich verlässt. Sie können die Funktion 'ptr.get()' verwenden, um einen unformatierten Zeiger zu erhalten, der ... cont unter – djrollins

+1

übergeben werden kann, damit andere die Ressource ändern können. Aber sie sollten nicht versuchen, es zu befreien. Zeiger bedeuten nicht automatisch die dynamische Speicherzuweisung - Sie können z. B. einen Zeiger für eine Stapelvariable erstellen. Sie müssen also wirklich darüber nachdenken, wem ** das Objekt gehört und wo es zugeordnet ist. Dies ist der Grund, warum die Smart Pointer gegenüber unformatierten Pointern empfohlen werden, da Sie der Ressource implizit eine Lebensdauer geben, die auf dem Besitz basiert, und sich daher keine Gedanken über die Freigabe des Speichers machen müssen. Sie müssen immer noch vorsichtig sein, rohe Zeiger zu "unique_ptr" -Daten zu baumeln, nachdem es freigegeben wurde. – djrollins