私はstd :: shared_ptrをカスタム削除機能とともに使用する方法を考えています。具体的には、SDL_Surfaceで次のように使用しています。
_std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....),SDL_FreeSurface);
_
コンパイルして正常に動作します。しかし、私は自分の削除プログラムを試してみたいので、どうやってやるのかわからない。 SDL_FreeSurfaceのドキュメントは次の場所にあります。
http://sdl.beuc.net/sdl.wiki/SDL_FreeSurface
sDL_FreeSurfaceは次のように宣言されています:
_void SDL_FreeSurface(SDL_Surface* surface);
_
テストとして、その情報を確認しながら、次の機能を試しました。
_void DeleteSurface(SDL_Surface* surface)
{
std::cout << "Deleting surface\n";
SDL_FreeSurface(surface);
}
_
ただし、g ++でコンパイルすると、次のエラーが発生します。
_error: no matching function for call to 'std::shared_ptr<SDL_Surface>::shared_ptr(SDL_Surface*, <unresolved overloaded function type>)'
_
私はgcc std :: shared_ptr実装のgnuドキュメントを見てきましたが、あまり理解できません。私は何を間違えていますか?
編集:私はそれ以来問題を絞り込みましたが、上記の元の質問を残します。私が持っていたのはGameクラスでした。これを基本的な実装に分解すると、次のようなものになりました。
_class Game {
public:
/* various functions */
private:
void DeleteSurface(SDL_Surface* surface);
bool CacheImages();
std::vector<std::shared_ptr<SDL_Surface> > mCachedImages;
/* various member variables and other functions */
}
_
上記のDeleteSurface
の実装、およびCacheImages()
の実装:
_bool CacheImages()
{
mCachedImages.Push_back(std::shared_ptr<SDL_Surface>(SDL_LoadBMP(...),DeleteSurface);
return true;
}
_
上記のエラーはどのゲームに影響しますか。ただし、DeleteSurface()
関数を変更せずにGame
クラスの外側に移動すると、コードがコンパイルされます。問題を引き起こしているDeleteSurface
クラスにGame
関数を含めることについてはどうですか?
std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....), [=](SDL_Surface* surface)
{
std::cout << "Deleting surface\n";
SDL_FreeSurface(surface);
});
または
void DeleteSurface(SDL_Surface* surface)
{
std::cout << "Deleting surface\n";
SDL_FreeSurface(surface);
}
std::shared_ptr<SDL_Surface>(SDL_LoadBMP(....), DeleteSurface);
編集:
更新された質問を見ると、DeleteSurface
は非メンバー関数である必要があります。そうでない場合は、std::bind
またはstd::mem_fn
または他のメンバー関数ポインターアダプター。
このコードは、オブジェクトメソッドとして削除機能を使用した共有ポインターの構築例を示しています。使用する_std::bind
_命令を表示します。
この例は、単純なオブジェクトリサイクラです。オブジェクトへの最後の参照が破棄されると、オブジェクトはリサイクラ内の空きオブジェクトプールに返されます。
get()
メソッドとadd()
メソッドにキーを追加し、オブジェクトを_std::map
_に保存することにより、レシラーをオブジェクトキャッシュに簡単に変更できます。
_class ObjRecycler
{
private:
std::vector<Obj*> freeObjPool;
public:
~ObjRecycler()
{
for (auto o: freeObjPool)
delete o;
}
void add(Obj *o)
{
if (o)
freeObjPool.Push_back(o);
}
std::shared_ptr<Obj> get()
{
Obj* o;
if (freeObjPool.empty())
o = new Obj();
else
{
o = freeObjPool.back();
freeObjPool.pop_back();
}
return std::shared_ptr<Obj>(o,
std::bind(&ObjRecycler::add, this, std::placeholders::_1));
}
}
_