假设我们有以下代码
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) 是如何实现的? move dtor 后仍然在 rhs 上调用,这不会产生预期的效果? 我想是这样的
Image::Image( Image && rhs )
{
pBitmap_ = std::move(rhs.pBitmap_);
rhs.pBitmap_ = nullptr;
}
然后在 dtor 中检查 null 应该可以解决问题,但是有更好的方法吗?
最佳答案
解决方案是不要自己做,而是使用语言的库设施:
struct FiBitmapDeleter {
void operator()(FIBITMAP *pBitmap) { FreeImage_Unload(pBitmap); }
};
class Image {
private:
std::unique_ptr<FIBITMAP, FiBitmapDeleter> pBitmap_;
};
现在您不需要编写析构函数、 move 构造函数或 move 赋值运算符。此外,您的类会自动删除其复制构造函数和复制赋值运算符,因此您无需担心这些,完成了五规则。
另一种方法是专门化 default_delete
,这意味着您不需要为 unique_ptr
提供删除器类型:
namespace std {
template<> struct default_delete<FIBITMAP> {
void operator()(FIBITMAP *pBitmap) { FreeImage_Unload(pBitmap); }
};
}
std::unique_ptr<FIBITMAP> pBitmap_;
这具有全局影响,因此只有当您确信您的代码是程序中唯一可以执行此特化的代码时,您才应该这样做。
关于c++ - 处理 C 库对象时如何实现 std::move(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13292432/