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


2 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).

Question

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