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

可以帮助的一件事是,所有将与之合作Bar::bar的班级都是一个班级的孩子!

这可以实现吗?如何实现?如何修复我的代码?提前致谢!

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 回答