3

免責事項私は使用しないか、他BOOSTのライブラリ

最後に、PointerToMemberFunctionの仕組みを学びました。これは私のコード例です

#include <iostream>

using namespace std;

class Foo
{
        public:
                void foo ( )
                {
                        cout << "I'm a foo method\n";
                };
};

class Bar
{
        public:
                void bar ( Foo* fooPtr , void(Foo::*fooFnPtr)() )
                {
                        (fooPtr->*fooFnPtr)();
                };
};

int main()
{
        Foo* foo = new Foo();
        Bar* bar = new Bar();

        bar->bar ( foo , &Foo::foo );

        return 0;
}

さて、何が問題なのか。Bar::bar実際のプロジェクトでは、どのクラスfooFnPtrが へのポインターであるかがわからないため、何らかの方法で変更する必要があります。つまりBar::bar、 だけでなく、どのクラスでも動作する必要がありFooます。私にはわかりませんが、渡されるクラスのインスタンスへのポインタBar::barです。

役立つことの 1 つは、動作するすべてのクラスがBar::bar1 つのクラスの子であることです。

これは達成可能ですか?コードを修正するにはどうすればよいですか? 前もって感謝します!

4

2 に答える 2

9

barテンプレート関数を作成できます:

template<class T>
void bar ( T* fooPtr , void(T::*fooFnPtr)() )
{
    (fooPtr->*fooFnPtr)();
}

もちろん、共通の基本クラスに存在するメンバーへのポインターのみを渡したい場合は、次のように簡単に実行できます。

#include <iostream>

using namespace std;

class Foo
{
        public:
                virtual void foo ( )
                {
                        cout << "I'm a foo method\n";
                };
};

class Derived: public Foo
{
        public:
                virtual void foo ( )
                {
                        cout << "I'm a Derived method\n";
                };
};


class Bar
{
        public:
                void bar ( Foo* fooPtr , void(Foo::*fooFnPtr)() )
                {
                        (fooPtr->*fooFnPtr)();
                }
};

int main()
{
        Derived* derived = new Derived();
        Bar* bar = new Bar();

        bar->bar ( derived , &Foo::foo );

        return 0;
}
于 2012-08-24T14:09:05.567 に答える
1

クロージャーとデリゲート、または C++ で同等のものを求めていると思います。つまり、それらは呼び出すことができるインスタンスであり、クラス インスタンス (またはインスタンス自体) へのポインターとそこにあるメソッドへのポインターの両方を含みます。

std::bind を見てください。関数またはメソッドのパラメーターとして均一に型指定された引数を使用する必要がある場合に備えて、これらは通常、すべて std::function<...> に変換可能なテンプレート クラスの不可解なインスタンスを返します。

したがって、コードは次のようになります。

    void Bar::bar(std::function<void()> f)
    { 
       ....
    }

    Foo* foo = new Foo();
    Bar* bar = new Bar();
    auto f = std::bind( &Foo::foo, foo);
    bar->bar ( f );

もちろん、どのライブラリも使用しないことにした場合でも、それらのライブラリが以前に問題をどのように解決したかを調べて、可能な限り最善の方法で車輪を再発明できるようにすることができます。

于 2012-08-24T14:06:39.040 に答える