问题
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"?
回答1:
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.
回答2:
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
回答3:
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