2009-06-22 15 views
5

Desidero restituire due valori, uno dei quali è un nuovo oggetto. Posso farlo utilizzando std::pair:Restituzione di un nuovo oggetto con un altro valore

class A { 
//... 
}; 

std::pair<A*, int> getA() 
{ 
    A* a = new A; 
    //... 
} 

Per rendere il codice sicuro rispetto alle eccezioni, vorrei fare:

std::pair<std::auto_ptr<A>, int> getA() 
{ 
    std::auto_ptr<A> a(new A); 
    //... 
} 

Ma questo non verrà compilato come il auto_ptr non possono essere copiati senza modificare la auto_ptr da copiare. Ok, questo significa che auto_ptr non si compongono bene come altri tipi (in un altro modo). Qual è un buon modo per restituire un nuovo oggetto in questo caso?

Un'alternativa è quella di restituire un shared_ptr e un altro è un riferimento inout. Ma sto cercando qualche altra alternativa. Posso fare qualcosa come:

class AGetter 
{ 
    void getAExecute() 
    { 
     //... 
     // set a_ and i_ 
    } 
    std::auto_ptr<A> getA() const 
    { 
     return a_.release(); 
    } 
    int getInt() const 
    { 
     return i_; 
    } 
    private: 
    std::auto_ptr<A> a_; 
    int i_; 
}; 

C'è un modo migliore?

risposta

2

basta creare una nuova classe e tornare quella classe

class Result 
{ 
    A* a; 
    int i; 
public: 
    Result(A*a, int i) : a(a), i(i) { 
    } 
    ~Result() { 
     delete a; 
    } 
    // access functions, copy constructor, ... 
}; 

Result getA() { 
    //...  
    return Result(new A, intValue); 
} 
1

Non è bello, ma si potrebbe tornare l'altro valore tramite un puntatore o riferimento argomento:

int i; 
std::auto_ptr<A> a = getA(&i); 
5

Ci sono due principali modi per gestire questo problema:

  1. fare la pulizia da soli, via prova/cattura.
  2. Utilizzare un tipo di gestione della memoria automatica, ad esempio shared_ptr.

auto_ptr non funziona proprio in questo tipo di casi, come hai scoperto, ma il nuovo standard e aumentare entrambi contengono i puntatori di riferimento-contato che fare quello che vuoi. Fateci sapere cosa non vi piace su shared_ptr, e forse possiamo suggerire un'alternativa.

+0

shared_ptr è leggermente/banalmente inefficiente e virale. Argomentazioni non molto forti contro shared_ptr, ma ancora un fattore contro di loro (nel 10% dei casi). –

+1

fortunatamente, lo standard successivo contiene unique_ptr, che può essere spostato insieme alla coppia che lo contiene. –

1

Perché non attraverso due parametri di riferimento?

class AGetter 
{ 
    // .. 
    void get(std::auto_ptr<A>& a, int& i) 
    { 
     a = a_.release(); 
     i = i_; 
    } 
    // .. 
}; 
+0

Questo è ciò che intendevo per riferimenti inout. I riferimenti di Inout sono ok, ma sarete d'accordo su un compromesso (la firma della funzione non chiarisce gli effetti della chiamata della funzione). –

3

Un shared_ptr sarebbe l'ideale in quella situazione, ma se davvero non si vuole utilizzare quelli che potrebbe restituire un auto_ptr a una coppia che contiene l'oggetto e l'int invece.

Problemi correlati