2

次のコードがあるとしましょう

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をチェックすることでうまくいくはずですが、もっと良い方法はありますか?

4

1 に答える 1

6

解決策は、自分でそれを行うのではなく、言語のライブラリ機能を使用することです。

struct FiBitmapDeleter {
    void operator()(FIBITMAP *pBitmap) { FreeImage_Unload(pBitmap); }
};

class Image {
private:
    std::unique_ptr<FIBITMAP, FiBitmapDeleter> pBitmap_;
};

これで、デストラクタ、ムーブコンストラクタ、またはムーブ代入演算子を作成する必要がなくなりました。また、クラスではコピーコンストラクターとコピー代入演算子が自動的に削除されるため、これらについても心配する必要はなく、5つのルールを完了できます。

別の方法は、特殊default_delete化することです。つまり、次のアドレスに削除タイプを指定する必要はありませんunique_ptr

namespace std {
    template<> struct default_delete<FIBITMAP> {
        void operator()(FIBITMAP *pBitmap) { FreeImage_Unload(pBitmap); }
    };
}
std::unique_ptr<FIBITMAP> pBitmap_;

これにはグローバルな影響があるため、この特殊化を実行する可能性のあるプログラム内のコードが自分のものだけであると確信している場合にのみ実行する必要があります。

于 2012-11-08T15:58:57.650 に答える