Normally, when you develop software in C++, it is your choice whether you want to pay
attention to exception safety, or to use exceptions at all in your code. Rvalue references
are a bit different in this regard. When you overload the copy constructor and the copy
assignment operator of a class for the sake of move semantics, it is very much recommended that you
do the following:
-
Strive to write your overloads in such a way that they cannot throw exceptions. That is
often trivial, because move semantics typically do no more than exchange pointers and
resource handles between two objects.
-
If you succeeded in not throwing exceptions from your overloads, then make sure to advertise that
fact using the new
noexcept keyword.
If you don't do both of these things, then there is at least one very common situation where your move semantics
will not be applied despite the fact that you would very much expect it: when an std::vector gets
resized, you certainly want move semantics to happen when the existing elements of your vector are being relocated
to the new memory block. But that won't happen unless both of 1. and 2. above are satisfied.
You don't really have to understand the reasons for this behavior. Observing the recommendations 1. and 2. above
is easy enough, and it's all you really need to know. However, having an understanding that runs a little deeper
than absolutely necessary has never hurt anybody. I recommend reading Item 14 (and all the other items, for that matter) of Scott
Meyers' book “Effective Modern C++.”
|