mientras miraba un código, me topé con:
throw /*-->*/new std::exception ("//...
y siempre pensé que no necesitas / no deberías usar newaquí.
¿Cuál es la forma correcta? ¿Ambos están bien? Si es así, ¿hay alguna diferencia?
Por cierto, por lo que puedo ver mientras "grepping" con PowerShell boost libs nunca se usan throw new.
PD: también encontré un código CLI que usa throw gcnew. ¿Eso esta bien?

throw gcnewsería útil, por ejemplo. si desea que el código administrado detecte su excepción. ¿Alguien puede corregirme en eso?System::Exceptiones generalmente una referencia a un objeto administrado en el montón recolectado de basura. Siempre he tiradogcnewy atrapadoSystem::Exception ^. Por supuesto, también utilizofinallytodo el tiempo en C ++ / CLI, aunque a menudo no se mezclan con excepciones de C ++ en el mismotrybloque, no estoy seguro de por qué.Respuestas:
La forma convencional de lanzar y capturar excepciones es lanzar un objeto de excepción y capturarlo por referencia (generalmente
constreferencia). El lenguaje C ++ requiere que el compilador genere el código apropiado para construir el objeto de excepción y limpiarlo adecuadamente en el momento apropiado.Lanzar un puntero a un objeto asignado dinámicamente nunca es una buena idea. Se supone que las excepciones le permitirán escribir código más sólido ante condiciones de error. Si lanza un objeto de excepción de la manera convencional, puede estar seguro de que si es capturado por una cláusula catch que nombra el tipo correcto, por a
catch (...), ya sea que se vuelva a lanzar o no, se destruirá correctamente en el momento adecuado. (La única excepción es si nunca se detecta, pero esta es una situación no recuperable, se mire como se mire).Si lanza un puntero a un objeto asignado dinámicamente, debe asegurarse de que, sea cual sea el aspecto de la pila de llamadas en el punto en el que desea lanzar su excepción, hay un bloque de captura que nombra el tipo de puntero correcto y tiene la
deletellamada adecuada . Su excepción nunca debe ser capturada acatch (...)menos que ese bloque vuelva a lanzar la excepción que luego es capturada por otro bloque de captura que maneja correctamente la excepción.Efectivamente, esto significa que ha tomado la función de manejo de excepciones que debería facilitar la escritura de código robusto y dificulta la escritura de código que sea correcto en todas las situaciones. Esto deja de lado el problema de que será casi imposible actuar como código de biblioteca para el código de cliente que no espera esta característica.
fuente
No es necesario usarlo
newal lanzar una excepción.Solo escribe:
y capturar como:
Tenga en cuenta que
yourexceptiondebe derivar de formastd::exceptiondirecta o indirecta.fuente
new? por qué derivaryourexceptiona partirstd::exception?throw std::exception;funciona? g ++ no parece compilarlo ...std::exceptiones un tipo, y no puedes lanzar un tipo , tienes que lanzar un objeto . Entonces la sintaxis debería ser esta:throw std::exception();Eso se compilará. Ahora bien, qué tan bueno es eso, es una pregunta completamente diferente.El lanzamiento
new std::exceptiones correcto si el sitio de la llamada espera atrapar unstd::exception*. Pero nadie esperará captar un puntero a una excepción. Incluso si documentas que eso es lo que hace tu función y las personas leen la documentación, es probable que se olviden e intenten captar una referencia a unstd::exceptionobjeto.fuente
new std::exceptionsolo es correcto si el sitio de llamada espera capturar un puntero Y espera hacerse cargo de la administración de la excepción de asignación Y nunca habrá casos en los que su función sea llamada por algo que no captura explícitamente el puntero correcto (catch(...)o ningún manejo) de lo contrario habrá una fuga de objetos. En resumen, esto se puede aproximar como "nunca".Las preguntas frecuentes de C ++ tienen una buena discusión sobre esto:
Básicamente, "a menos que haya una buena razón para no capturar por referencia. Evite capturar por valor, ya que eso hace que se haga una copia y la copia puede tener un comportamiento diferente al que se lanzó. Solo en circunstancias muy especiales debe capturar por puntero". "
fuente
Aes distinto del tipo,A*así que si lo hagothrow A(), NO puedocatch(A* e)entenderlo, ya que es un tipo completamente diferente.El operador nuevo no puede garantizar que nunca generará una excepción. Por esta razón, usarlo para lanzar una excepción "válida" (prevista) produciría un código que no puede garantizarse que no se bloquee. Dado que puede haber solo una excepción a la vez, y su programa intenta lanzar dos antes de que cualquiera de ellas pueda ser detectada, lo mejor que puede hacer una implementación es abortar inmediatamente su programa, por ejemplo, llamando a std :: terminate.
fuente