Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

exception with non virtual destructor c++

When we go out of catch block scope, does the exception destructor get called? (In case we don't rethrow it)

Suppose I have class A, and that its destructor is not virtual. B inherits A. Suppose some function threw object of B class as an exception, and it was caught by a catch block

catch(A& a){
...
}

If the exception destructor should be called when go out of catch scope, in this case only the base class A's destructor will be called?

Cornstalks: live trial result in calling both class destructor.

It contradicts my logic. Explain someone?

like image 733
Day_Dreamer Avatar asked Feb 05 '15 20:02

Day_Dreamer


2 Answers

OK, someone already answered your first question. I'll focus on this one:

if the exception destructor should be called when go out of catch scope, in this case only the base class A's d'tor will be called?

The implementation will always destroy the exception object properly regardless of how it is caught. The implementation constructs the exception object, so it knows how to destroy it. This is not the same as when you call delete through a pointer, because in that case there is incomplete information about the complete type of the object at that point (it may have been newed somewhere else) unless a virtual destructor exists.

Were this not the case, catch (...) would never work at all.

like image 122
Brian Bi Avatar answered Sep 20 '22 14:09

Brian Bi


when we go out of catch block scope, does the exception destructor is called? (In case we don't rethrow it)

Yes:

[C++11: 15.1/4]: [..] The exception object is destroyed after either the last remaining active handler for the exception exits by any means other than rethrowing, or the last object of type std::exception_ptr (18.8.5) that refers to the exception object is destroyed, whichever is later. [..]


if the exception destructor should be called when go out of catch scope, in this case only the base class A's d'tor will be called?

No:

#include <iostream>

struct A
{
    A() { std::cout << "A()"; }
    A(const A&) { std::cout << "A(const A&)"; }
    A(A&&) { std::cout << "A(A&&)"; }
    ~A() { std::cout << "~A()"; }
};

struct B : A
{
    B() { std::cout << "B()"; }
    B(const B&) { std::cout << "B(const B&)"; }
    B(B&&) { std::cout << "B(B&&)"; }
    ~B() { std::cout << "~B()"; }
};

int main()
{
    try {
        throw B();
    }
    catch (A&) {
    }
}

// Output: A()B()~B()~A()
like image 34
Lightness Races in Orbit Avatar answered Sep 20 '22 14:09

Lightness Races in Orbit