General C++ question on constructors
-
-
Hi, I have a general question on constructors in C++. If my constructor throws an exception is the object created? If so, is it a valid object? Can I invoke the methods of the class using that object? How should you handle this scenario? Thanks, Mel
May be the answer can change depending on compiler, but as far as I know, the constructor is called after memory allocation has occurred and its first instructions (think as executed at the "open brace") are "call the bases constructors and call the members constructors". At that point the object can be assumed as effectively constructed and formed. The problem is another: if your object is used as a base of another object and your constructor throws an exception ... The "other" object is not properly constructed. But the memory is allocated. But the other object constructor cannot handle the exception as well, since it didn’t reach any possible "try/catch" block. (It escaped from its open brace) In fact your exception escapes the constructors leaving the instantiator (the piece of program that asked to create the outer object) with an allocated, but partially constructed object. The fact that "delete" can be properly called by the calling program, mostly depend on what constructors and destructors do. Moral: avoid to throw exceptions in constructors... a "two phase construction" (by calling a separate "init" function after the construction) can be safer and give a more predictable behaviour. 2 bugs found. > recompile ... 65534 bugs found. :doh:
-
Hi, I have a general question on constructors in C++. If my constructor throws an exception is the object created? If so, is it a valid object? Can I invoke the methods of the class using that object? How should you handle this scenario? Thanks, Mel
-
Hi, I have a general question on constructors in C++. If my constructor throws an exception is the object created? If so, is it a valid object? Can I invoke the methods of the class using that object? How should you handle this scenario? Thanks, Mel
The C++ standard says that if a constructor throws an exception any memory allocated will be freed, but no destructor will be called. It is not a valid object and you cannot invoke members. If you try to do so the behaviour is undefined. In C++, undefined usually means it will crash. I'm pretty sure that VC++ implements this behaviour correctly. In essence it wraps a
new
operation in atry
/catch
block and calls::operator delete
(or the class'soperator delete
, if it or a base class implements one), if C++ exception handling is enabled. Stability. What an interesting concept. -- Chris Maunder