Let's say I have class that acts as a "smart pointer" and releases some kind of system resource when destroyed.
class Resource{
protected:
ResourceHandle h;
public:
Resource(ResourceHandle handle)
:h(handle){
}
~Resource(){
if (h)
releaseResourceHandle(h);//external function, probably from OS
}
};
And I have some function that returns value used for initialization of "Resource":
ResourceHandle allocateHandle();
Now, if I do this in my code:
Resource resource(allocateHandle());
AND allocateHandle() throws an exception, what exactly will happen? Will the cras开发者_运维百科h occur during construction of Resource() or before the construction?
Common sense tells me that because exception is thrown before allocateHandle returns, execution won't even enter Resource() constructor, but I'm not exactly sure about it. Is this a correct assumption?
Arguments are evaluated before any function call -- in this case the constructor --. Therefore, the exception is thrown before the constructor call
Yes you are correct (as everybody else has said).
But what you are alluding to (I think).
What happens to the object if the constructor was entered and the exception is thrown.
Would the destructor still get executed or not?
Destructors are only fired if the constructor actually finished (if an exception is throw that escapes the constructor then the constructor is not finished). In this case the constructor is not entered and thus the object does not exist and therefore the destructor will not be executed.
What happens if the exception is thrown while the constructor is executing.
In this case because the constructor was not completed the destructor will never be executed either, but what about all the member fields? If the constructor is left via an exception then all fully formed members will have their destructors called (A fully formed member is a member whose constructor has been called and completed successfully).
This is a correct assumption.
If the compiler entered the constructor, what value could it pass in from a function that didn't return?
Yes, your assumption is correct.
At this point you are only creating your parameters and pushing them on the stack. The Object of "Resource" is not even formed!
Therefore, an exception will not call the destructor during stack unwinding.
精彩评论