Consider the following:
class Example : boost::noncopyable
{
HANDLE hExample;
public:
Example()
{
hExample = InitializeHandle();
}
~Example()
{
if (hExample == INVALID_HANDLE_VALUE)
{
return;
}
FreeHandle(hExample);
}
Example(Example && other)
: hExample(other.hExample)
{
other.hExample = INVALID_HANDLE_VALUE;
}
Example& operator=(Example &&other)
{
std::swap(hExample, other.hExample); //?
return *this;
}
};
My thinking here is that the destructor will be running on "other" shortly, and as such I don't have to implement my destructor logic again in the move assignment operator by using swap. But I'm not sure that's a reasonable assumption. Would this be "okay"?
It should be ok, but it's scarcely any better than the recommended technique of pass-by-value, in which case the move constructor would be used in this situation.
Imagine the following:
// global variables
Example foo;
struct bar {
void f() {
x = std::move(foo); // the old x will now live forever
}
Example x;
}
A similar idiom, copy-and-swap (or in this case, move-and-swap), ensures that the destructor is run immediately, which I believe is a better semantic.
Example& operator=(Example other) // other will be moved here
{
std::swap(hExample, other.hExample);
return *this;
} // and destroyed here, after swapping
My thinking here is that the destructor will be running on "other" shortly
Then your thinking is flawed. You can move from any object you have non-const access to. And the object can continue to live indefinitely after this.
It is technically correct to put your current data in the old object. But it's not a good idea. It's better to use a stack variable:
Example& operator=(Example &&other)
{
Example temp(std::move(other)); //other is now empty.
std::swap(hExample, temp); //our stuff is in `temp`, and will be destroyed
return *thisl
}
Or better yet (if you're not using Visual Studio) store your stuff in a wrapper that supports movement correctly, and let the compiler-generated move constructor do the job for you.
来源:https://stackoverflow.com/questions/9746748/does-it-make-sense-to-reuse-destructor-logic-by-using-stdswap-in-a-move-assign