2012-04-05 14 views
7

tengo un problema con auto_ptr en las clases de excepción, que con el tiempo he reducido a:Por qué no puedo tener un auto_ptr en una clase de excepción

#include <memory> 

class MyException 
{ 
    std::auto_ptr<int> m_foo2; 
}; 

int main() 
{ 
    try 
    { 
     throw MyException(); 
    } 
    catch (const MyException&) 
    { 

    } 
    return 0; 
} 

Esta falla al compilar con:

/perforce/unstable/test/Common/Exceptions/TestException4.cpp: In function 'int main()': /perforce/unstable/test/Common/Exceptions/TestException4.cpp:12: error: no matching function for call to 'MyException::MyException(MyException)' /perforce/unstable/test/Common/Exceptions/TestException4.cpp:4: note: candidates are: MyException::MyException() /perforce/unstable/test/Common/Exceptions/TestException4.cpp:4: note: MyException::MyException(MyException&) /perforce/unstable/test/Common/Exceptions/TestException4.cpp:12: error: in thrown expression

Y el error desaparece si elimino el auto_ptr.

¿Esto se debe a que se está copiando o asignando la excepción? ¿Hay alguna manera de usar auto_ptr s en una excepción?

+0

Guau, respuestas de alta calidad aquí. Debe ser una buena pregunta. :) – sje397

Respuesta

9

Is this because the exception is being copied or assigned?

Indeed it is. La norma especifica cómo se produce una excepción en C++ 11 15.1/3:

A throw-expression initializes a temporary object, [...]. The temporary is an lvalue and is used to initialize the variable named in the matching handler.

La inicialización se realiza con el constructor de copia implícita. Esto se declara como MyException(MyException&), ya que hay un miembro que requiere un argumento de referencia que no es const (como se especifica en C++ 11 12.8/9). El objeto temporal no puede vincularse a una referencia que no sea const, por lo que la construcción falla.

Is there a way of using auto_ptrs in an Exception?

Si usted es capaz de utilizar C++ 11, entonces se podría utilizar en lugar unique_ptr, y consignar auto_ptr a las entrañas de la historia. Su clase tendría un constructor de movimiento implícito, declarado como MyException(MyException&&), que podría usarse para inicializarlo desde un temporal.

lo contrario, podría arrojar un valor no temporal:

MyException ex; 
throw ex; 

o usted podría cortar su clase para permitir la inicialización desde una referencia const añadiendo un constructor de copia explícita y utilizando const_cast o mutable a permitir que eso copie el auto_ptr, pero eso es potencialmente peligroso y no lo recomendaría.

Cuestiones relacionadas