假设我们有以下代码
class Image
{
public:
Image(const std::string & path)
{
pBitmap_ = FreeImage_Load( imageFormat, pathname.c_str() );
}
~Image()
{
FreeImage_Unload(pBitmap_);
}
private:
FIBITMAP * pBitmap_;
};
如何实施Image(Image&& rhs)? 在移动dtor后仍然会调用rhs,这不会产生预期的效果? 我想像
这样的东西Image::Image( Image && rhs )
{
pBitmap_ = std::move(rhs.pBitmap_);
rhs.pBitmap_ = nullptr;
}
然后在dtor中检查null应该可以解决问题,但是有更好的方法吗?
答案 0 :(得分:6)
解决方案是不能自己动手,但使用该语言的库设施:
struct FiBitmapDeleter {
void operator()(FIBITMAP *pBitmap) { FreeImage_Unload(pBitmap); }
};
class Image {
private:
std::unique_ptr<FIBITMAP, FiBitmapDeleter> pBitmap_;
};
现在您不需要编写析构函数,移动构造函数或移动赋值运算符。此外,您的类会自动删除其复制构造函数和复制赋值运算符,因此您也不必担心这些,完成五条规则。
另一种方法是专门化default_delete
,这意味着您不需要向unique_ptr
提供删除类型:
namespace std {
template<> struct default_delete<FIBITMAP> {
void operator()(FIBITMAP *pBitmap) { FreeImage_Unload(pBitmap); }
};
}
std::unique_ptr<FIBITMAP> pBitmap_;
这具有全局效果,所以只有当您确信自己是程序中可能执行此专业化的唯一代码时,才应该这样做。