There is following code:
class Member
{
public:
~Member() noexcept(false) {}
};
class A
{
public:
virtual ~A() {}
};
class B : public A
{
public:
Member m;
};
The error is:
main.cpp:13:7: error: looser throw specifier for ‘virtual B::~B() noexcept (false)’
class B : public A
^
main.cpp:10:11: error: overriding ‘virtual A::~A() noexcept’
virtual ~A() {}
^
Why does the destructor in class B is marked as noexcept(false)? It seems that it somehow gets it from Member class. It was compiled by g++ 6.3.
Any user-defined destructor is noexcept(true) by default, unless the declaration specifies otherwise, or the destructor of any base or member is noexcept(false) . Any deallocation function is noexcept(true) by default, unless the declaration specifies otherwise.
Item 14, page 94: 'By default, all memory deallocation functions and all destructors -both user-defined and compiler-generated- are implicitly noexcept. There is thus no need to declare them noexcept. (Doing so doesn't hurt anything, it's just unconventional.)'
No. You never need to explicitly call a destructor (except with placement new). A derived class's destructor (whether or not you explicitly define one) automagically invokes the destructors for base class subobjects. Base classes are destructed after member objects.
B's destructor will destroy m, which is not a noexcept operations. You can't be sure that ~B won't throw, so it is also noexcept(false).
See http://en.cppreference.com/w/cpp/language/destructor#Implicitly-declared_destructor :
[...] In practice, implicit destructors are noexcept unless the class is "poisoned" by a base or member whose destructor is noexcept(false).
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