Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overrriding destructor of std:exception

The following program does not compile in g++ 4.4 if line 8 is commented. Why? It seems that when I override std::exception constructor, I must override its destructor as well. What's the reason for this?

#include<iostream>
#include<exception>
using namespace std;

class A : public exception {
public:
    A(string msg) : _msg(msg) {}
    //~A() throw(){};                     // line 8
    const char* what() const throw() { return _msg.c_str();}    
private:
    string _msg;
};

int main()
{
}

The compilation error is:

error: looser throw specifier for ‘virtual A::~A()’
like image 947
cpp Avatar asked Aug 24 '13 09:08

cpp


1 Answers

This is because the destructor requires a throw() specifier. If you don't specify it in your class the compiler writes it's own default destructor for you class, and the default destructor doesn't specify that you don't throw exceptions.

This is correct, since the public destructor of std::exception also specifies throw()

~A() throw(){};

from the standard (N3225) 12.4.4 :

If a class has no user-declared destructor, a destructor is implicitly declared as >defaulted (8.4). An implicitly- declared destructor is an inline public member of its class.

Therefore, if you don't declare the destructor yourself the compiler creates the next destructor. If all your exception member destructors where nothrow qualified, the compiler will probably generate a destructor with throw() specified.

~A(){};

And technically one could throw an exception from this destructor, but that would be very bad programming style, therefore an exception deriving from std::exception guarantees that you don't throw any exceptions in the destructor of a std::exception derived class.

Edit Newer compilers will provide a destructor that does have a noexcept specifier if the destructor of std::string is noexcept specified. And other compilers will also generate a noexcept destructor if all member's destructors don't throw exceptions (are noexcept qualified). This is mandated by C++11 standard in chapter 15.4. [except.spec]

14 An implicitly declared special member function (Clause 12) shall have an exception-specification. If f is an implicitly declared default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment operator, its implicit exception-specification specifies the type-id T if and only if T is allowed by the exception-specification of a function directly invoked by f’s implicit definition; f shall allow all exceptions if any function it directly invokes allows all exceptions, and f shall allow no exceptions if every function it directly invokes allows no exceptions. [...]

like image 134
hetepeperfan Avatar answered Oct 19 '22 10:10

hetepeperfan