Suppose I have:
class Foo
{
public:
virtual ~Foo()=default;
};
What is the exception-specification on the defaulted destructor? Is the defaulted destructor equivalent to:
virtual ~Foo() {};
or
virtual ~Foo() throw() {};
or
virtual ~Foo() noexcept {};
Section 15.4 of the C++11 standard says it depends on the exception specifications of the functions directly invoked by the destructor's implicit definition. In this case there are no members, and no base classes, so AFAIK there are no functions directly invoked by the implicit destructor. Is this an ambiguity (or omission) in the standard?
It matters, of course, because if it implicitly has throw(), then all subclasses must declare their destructors with throw(). Don't tell me it's a bad idea to throw exceptions in destructors, I know that. I deal with lots of legacy code where exception specs were not used at all.
As a point of information, when I tried:
class SubFoo : public Foo
{
public:
virtual ~SubFoo();
};
I got an error (mismatched exception specs) in GCC 4.4 (although I admit I may not have had the right command line switches), but not in XCode 4.3 using the "11" compilers.
The destructor is not user-provided (meaning, it is either implicitly declared, or explicitly defined as defaulted on its first declaration) The destructor is not virtual (that is, the base class destructor is not virtual) All direct base classes have trivial destructors.
The default destructor calls the destructors of the base class and members of the derived class. The destructors of base classes and members are called in the reverse order of the completion of their constructor: The destructor for a class object is called before destructors for members and bases are called.
A virtual destructor is used to free up the memory space allocated by the derived class object or instance while deleting instances of the derived class using a base class pointer object.
A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete . A destructor has the same name as the class, preceded by a tilde ( ~ ). For example, the destructor for class String is declared: ~String() .
Back up to earlier in the same sentence (§15.4/14):
...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;..."
Therefore, if ~Foo
doesn't invoke any functions, it has an implicit declaration that allows no exceptions to be thrown.
According to §15.4/3:
Two exception-specifications are compatible if:
- both are non-throwing (see below), regardless of their form,
That's the case here, so it doesn't really matter whether the declaration is throw()
or noexcept
-- the two are compatible in any case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With