c++ Come "restituire un oggetto" in C ++?




3 Answers

Basta creare l'oggetto e restituirlo

Thing calculateThing() {
    Thing thing;
    // do calculations and modify thing
     return thing;
}

Penso che ti farai un favore se ti dimentichi dell'ottimizzazione e scrivi solo codice leggibile (dovrai eseguire un profilatore più tardi, ma non pre-ottimizzare).

c++ reference performance return

So che il titolo sembra familiare perché ci sono molte domande simili, ma sto chiedendo un aspetto diverso del problema (conosco la differenza tra avere cose in pila e metterle in pila).

In Java posso sempre restituire riferimenti ad oggetti "locali"

public Thing calculateThing() {
    Thing thing = new Thing();
    // do calculations and modify thing
    return thing;
}

In C ++, per fare qualcosa di simile ho 2 opzioni

(1) Posso usare i riferimenti ogni volta che ho bisogno di "restituire" un oggetto

void calculateThing(Thing& thing) {
    // do calculations and modify thing
}

Quindi usalo in questo modo

Thing thing;
calculateThing(thing);

(2) O posso restituire un puntatore ad un oggetto allocato dinamicamente

Thing* calculateThing() {
    Thing* thing(new Thing());
    // do calculations and modify thing
    return thing;
}

Quindi usalo in questo modo

Thing* thing = calculateThing();
delete thing;

Usando il primo approccio non dovrò liberare la memoria manualmente, ma per me rende il codice difficile da leggere. Il problema con il secondo approccio è che dovrò ricordare di delete thing; , che non sembra molto carino. Non voglio restituire un valore copiato perché è inefficiente (credo), quindi ecco che arrivano le domande

  • Esiste una terza soluzione (che non richiede la copia del valore)?
  • C'è qualche problema se mi atteno alla prima soluzione?
  • Quando e perché dovrei usare la seconda soluzione?



Hai provato a usare i puntatori intelligenti (se Thing è un oggetto molto grande e pesante), come auto_ptr:


std::auto_ptr<Thing> calculateThing()
{
  std::auto_ptr<Thing> thing(new Thing);
  // .. some calculations
  return thing;
}


// ...
{
  std::auto_ptr<Thing> thing = calculateThing();
  // working with thing

  // auto_ptr frees thing 
}



Per prima cosa hai un errore nel codice, vuoi dire Thing *thing(new Thing()); e return thing; solo return thing; .

  • Usa shared_ptr<Thing> . Deref come se fosse un puntatore. Verrà cancellato per te quando l'ultimo riferimento alla Thing contenuta non rientra nello scope.
  • La prima soluzione è molto comune nelle librerie naive. Ha delle prestazioni e un overhead sintattico, evitarlo se possibile
  • Utilizzare la seconda soluzione solo se è possibile garantire che non verranno generate eccezioni o quando le prestazioni sono assolutamente critiche (si interagirà con C o assembly prima che ciò diventi rilevante).





Related