Your question then amounts to a question about Exception Guarantees. There are 3 types of Exceptions Guarantees (that apply to functions):
- No exception guarantee at all (not really a type... but it may happen if no concern is given to the matter)
- Basic Exception Guarantee: Technically correct, but not Functionally correct (ie no resource is leaked, the program will terminate without an abrupt halt, but it may have undesired side-effects, like the payment being cashed-in but the command not being registered)
- Strong Exception Guarantee: All or Nothing (like a transaction), that is either everything is done right, or we rollback to the previous state.
- No Throw Exception Guarantee: This does not throw, ever, so no worry.
When you compose your function, you usually pick up existing functions with their own guarantees. It is difficult to increase the exception guarantee, that is your are generally limited by the weakest guarantee used.
W.r.t your question, it takes at least a Strong Exception Guarantee for the original object to be left untouched if an exception is thrown.
So, what happens if an exception is thrown during move-construction ? It depends on the guarantees exhibited by the sub-objects and the way you combined the calls...
- If an exception is thrown from a constructor, the object is not being built and all built subobjects are destroyed, in reverse order. This rule is also applicable to a move-constructor
- Unless you "wrap" the constructor in a try catch and somehow restore the objects that have been moved, they'll have lost their resources. Note that they must still be in a destructable state anyway, so technically the program will be correct.
In terms of exceptions guarantees, it means that by default, if all of the subobjects' constructors at least meet the Basic Exception Guarantee, then your move constructor will too, without any special care.
However, even if all the subobjects' constructors meet the Strong Exception Guarantee, it's unlikely you'll succeed in having your own move constructor meet it: this is the same issue that chaining transactions does not yield a transaction.
If only one of the subobjects' constructors may throw, and it meets the Strong Exception Guarantee, then your move constructor will naturally meet it itself if you initialize the throwing object first.
Hope this helped... exceptions are a wild beast to tame :)