Tres compiladores diferentes muestran tres comportamientos diferentes compilar este código:estándar Lo que el C++ dice acerca de perder especificador de tiro en el destructor por defecto
class MyException : public std::exception
{
public:
MyException(std::string str) : m_str(str) {}
virtual const char * what() const throw() {return m_str.c_str(); }
protected:
std::string m_str;
};
Sun C++ 5.8 Parche 121017-22 2010/09/29: advertencia Función MiExcepción :: ~ MiExcepción() puede lanzar sólo las excepciones producidas por la función std :: excepción :: ~ excepción() se anula
g ++ 3.4.3: error más flojo especificador de tiro para `MiExcepción virtuales :: ~ MyException() '
Visual Studio 2005: Es muy feliz (ni error o advertencia)
class exception {
public:
exception() throw();
exception (const exception&) throw();
exception& operator= (const exception&) throw();
virtual ~exception() throw();
virtual const char* what() const throw();
}
Yo sé cuál es el problema y cómo puedo solucionarlo:
class MyException : public std::exception
{
public:
MyException(std::string str) : m_str(str) {}
virtual const char * what() const throw() {return m_str.c_str(); }
~MyException() throw() {} <------------ now it is fine!
protected:
std::string m_str;
};
Sin embargo, estoy preguntándose qué dice el estándar en una situación específica.
Me corrió otra pequeña prueba en Visual Studio 2005 y he encontrado algo que me sorprende:
struct Base
{
virtual int foo() const throw() { return 5; }
};
struct Derived : public Base
{
int foo() const { return 6; }
};
int main()
{
Base* b = new Derived;
std::cout << b->foo() << std::endl; //<-- this line print 6!!!
delete b;
}
La firma de las dos funciones son diferentes. ¿Cómo puede esto funcionar? Parece que Visual Studio 2005 ignora por completo la especificación de excepción.
struct Base
{
virtual int foo() const throw() { return 5; }
};
struct Derived : public Base
{
int foo() { return 6; } // I have removed the const keyword
// and the signature has changed
};
int main()
{
Base* b = new Derived;
std::cout << b->foo() << std::endl; // <-- this line print 5
delete b;
}
¿Es este estándar de C++? ¿Hay alguna bandera mágica para establecer?
¿Qué hay de VS2008 y VS2010?
virtual int foo() const throw() y int foo() const ambos tienen la misma firma, creo - virtual y throw no cuentan. – JTeagle
Para ser honesto, las especificaciones de excepción generalmente se consideran una mala idea. No ganan nada, y si se lanza una excepción que no figura en la lista, todo el programa se cuelga. – 111111
gcc 3.4 y vs2k5? Si se trata de estándares compatibles, debe usar al menos gcc 4.5 y vs2010 para probar cualquier cosa – PlasmaHH