+ 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

4th Nov 2024, 10:44 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
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?
4th Nov 2024, 11:30 PM
Bob_Li
Bob_Li - avatar
+ 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.
6th Nov 2024, 11:01 AM
MO ELomari
MO ELomari - avatar
+ 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
5th Nov 2024, 4:32 AM
Ketan Lalcheta
Ketan Lalcheta - avatar
+ 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
5th Nov 2024, 12:07 PM
RuntimeTerror
RuntimeTerror - avatar
+ 1
Thanks MO ELomari nd Bob_Li
6th Nov 2024, 1:33 PM
Ketan Lalcheta
Ketan Lalcheta - avatar