+ 1
Exception in constructor
Hi Please refer code below: Why destructor cout statement is printed? Derived constructor throws exception so derived object is not constructed and hence destructor should not be called. Right? https://sololearn.com/compiler-playground/c7le3N1Qt4k4/?ref=app
5 ответов
+ 4
you get your expected behavior if you comment out these parts in your Derived class:
public:
//Derived() = default;
Derived(int)// : Derived()
By doing what you did, even though the parameterized constructor throws an error, the default constructor is still called, so Derived is still instantiated, so you see the Derived destructor being called.
you can confirm by changing your code to:
public:
Derived(){cout << "Derived default\n";}
Derived(int) : Derived()
you did not see it because
Derived = default;
did not have a cout.
The question is why did you write it this way? Are there any advantage to doing this?
+ 3
the <Derived::~Derived()> is called because the delegating constructor pattern makes the object fully constructed from the delegated constructor's perspective.
when <Derived::Derived(int)> delegates to <Derived::Derived()>, the default constructor completes fully.
let's go through it step by step:
when Derived d(1) is called:
- first, the delegating constructor <Derived::Derived()> is called.
- <Derived::Derived()> (default ctor) implicitly calls <Base::Base()> constructor ( prints "Base" ).
then inside <Derived::Derived(int)>:
- creates a local <Base> object "o" ( prints another "Base" )
- throws an exception before reaching "Derived" print statement
when the exception is thrown:
- the local <Base> object "o" is destroyed first ( prints "~Base" )
- the partially constructed <Derived> object is destroyed ( since <Derived> was fully constructed through delegation, its destructor is called, ( prints "~Derived" ) ).
- finally, the <Base> part of the <Derived> object is destroyed ( prints another "~Base").
different would happen without delegation, if the exception was thrown, the <Derived::~Derived()> would NOT be called because the object was never fully constructed.
so the key point is:
when using constructor delegation, the delegated constructor <Derived::Derived()> completes first, making the object fully constructed before the delegating constructor's body <Derived::Derived(int)> begins execution. that's why when the exception is thrown, the object needs full cleanup, including calling the <Derived::~Derived()>.
this is part of the C++ object lifetime rules - if an object is fully constructed, its destructor must be called when the object is destroyed, even if that destruction happens due to an exception.
+ 2
Just a dummy scenario. Not making much sense here , but in case default constructor doing some thing and same is done by parametric one. So, delegating to default constructor and then doing additional stuff where exception occurs.
So, in my thought, derived was not fully constructed and hence no destructor call was expected
+ 1
I learnt that for no reason should a constructor throw an exception without catching it in the same block. The reason, I can't remember but I think undefined behavior is part
+ 1
Thanks MO ELomari nd Bob_Li