0

ライブラリ内のオブジェクトのヒープメモリの管理を担当するMemMgrと呼ばれるC++シングルトンファクトリのようなクラスがあります。

#include <vector>
class MemMgr
{
    public:

        // Callback interface of functions to register with MemMgr
        typedef size_t (*MemSizeFunc)(void);

        void Register(MemSizeFunc memSizeFunc);

        static MemMgr & GetInst(void);

        // more public functionality related to managing memory

    private:

        // a vector (not a map) of functions pointers to keep track of
        std::vector<MemSizeFunc> m_memSizeFuncs;

        MemMgr(void);
        MemMgr(MemMgr const &);
        MemMgr & operator= (MemMgr const &);

        // more private functionality related to managing memory
};

私ができるようにしたいのは、管理対象メモリを利用したいクラスのオブジェクトが、管理対象メモリの量を計算して返す(非静的)メンバー関数を介してMemMgrに登録できるようにすることです。その特定のオブジェクトが必要とすること。次のようなもの:

class MemMgrUser
{
    public:

        MemMgrUser(void)
        {
            MemMgr::GetInst().Register(GetManagedMemSize);
        }

    private:

        size_t GetManagedMemSize(void)
        {
            // calculations involving member variables
        }
};

(次に、MemMgrが実際にメモリを割り当てる前に、割り当てるメモリの量を見つけるために、MemMgrに登録されているサイズ関連の関数を照会します。)

しかし、上記のアプローチを試してみると、コンパイラーは私に怒鳴ります。b/ cプレーンバニラ関数ポインターではなく、メンバー関数ポインターを登録しようとしています。

そのような機能をどのように実装できるかについて誰かが何か提案がありますか?テンプレートの実装(またはポリモーフィックな実装)がどのように実装されるかを確認するのに問題があります。

ありがとうございました、

アーロン

4

1 に答える 1

0

メンバー関数ポインタを登録しようとさえしません。これは、として指定する必要があります&MemMgrUser::GetManagedMemSize。メンバー関数のプレーン名は、それを呼び出す式を除いて使用できません。

ただし、メンバー関数ポインターがある場合でも、同じ見かけの署名のプレーン関数ポインターと同じように使用することはできません。メンバー関数を呼び出すには、常にそれを呼び出すオブジェクトが必要です。this関数で使用可能なポインターは、追加の非表示パラメーターです。

C ++ 11標準ライブラリの機能を使用できる場合typedef std::function<size_t (void)> MemSizeFunc;は、現在のtypedefの代わりに使用できます。これにより、そのシグニチャをとして呼び出すことができるさまざまな種類の関数および関数オブジェクトを格納できますMemSizeFuncGetManagedMemSize特に、適切なオブジェクトにバインドされたメンバー関数をMemMgrUser、たとえば次のように登録できます。

MemMgrUser()
{
   MemMgr::GetInst().Register(std::bind(&MemMgrUser::GetManagedMemSize, *this));
}
于 2013-02-11T20:39:01.600 に答える