2009-06-22 9 views
5

Deseo devolver dos valores, uno de los cuales es un objeto nuevo. Puedo hacer esto utilizando std::pair:Devolución de un nuevo objeto junto con otro valor

class A { 
//... 
}; 

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

Para hacer que el código de excepción de seguridad, me gustaría hacer:

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

Pero esto no se compilará como el auto_ptr no se puede copiar sin modificar el auto_ptr siendo copiado. Ok, esto significa que auto_ptr no se combina bien con otros tipos (de una forma más). ¿Cuál es una buena forma de devolver un objeto nuevo en este caso?

Una alternativa es devolver un shared_ptr y otra es una referencia inout. Pero estoy buscando alguna otra alternativa. Puedo hacer algo como:

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_; 
}; 

¿Hay una manera mejor?

Respuesta

2

Basta con crear una nueva clase y regresar esa clase

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

No es bonito, pero podría volver el otro valor a través de un puntero o una referencia argumento:

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

Hay dos formas principales para manejar este problema:

  1. hacer la limpieza usted mismo, a través de try/catch.
  2. Utilice algún tipo de gestión automática de memoria, como shared_ptr.

auto_ptr no funciona muy bien en este tipo de casos, ya que has descubierto, pero el nuevo estándar e impulsar ambos contienen punteros de referencia contado que hacer lo que quiera. Háganos saber lo que no le gusta de shared_ptr, y tal vez podamos sugerir una alternativa.

+0

shared_ptr es ligeramente/trivialmente ineficiente y viral. Argumentos no muy sólidos contra shared_ptr, pero aún así hacen un factor en contra de ellos (en 10% de los casos). –

+1

Afortunadamente, el siguiente estándar contiene unique_ptr, que se puede mover junto con el par que lo contiene. –

1

¿Por qué no a través de dos parámetros de referencia?

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

Eso es lo que quise decir con inout references. Las referencias de Inout son correctas, pero aceptará un compromiso (la firma de la función no deja en claro los efectos de llamar a la función). –

3

Un shared_ptr sería lo ideal en esa situación, pero si realmente no quiere usar los que podría devolver un auto_ptr a un par que contiene el objeto y el lugar int.

Cuestiones relacionadas