+ 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