指向班级成员的指针

时间:2010-03-04 13:02:22

标签: c++ boost-spirit member-function-pointers

我正在使用Boost Spirit解析器,并且在解析器解析时,语义操作会反映到类ParserActions的实例中。

以下是解析器的代码(相关部分)

struct urdf_grammar : public grammar<urdf_grammar> {

template <typename ScannerT>
        struct definition {

    definition(urdf_grammar const& self) {


        prog = (alpha_p >> *alnum_p)[&(self.actions.do_prog)];

    }

    rule<ScannerT> prog;

    rule<ScannerT> const&
            start() const {
        return prog;
    }
};

const ParserActions & actions;

explicit urdf_grammar(const ParserActions & actions = ParserActions()) : actions(actions) {
}  
};

3 个答案:

答案 0 :(得分:3)

要获取成员变量或函数的地址,请使用:

&MyClass::MyMember

要调用成员函数指针,请使用以下之一:

(my_class.*ptr_to_member)( /* arguments */ )
(my_ptr->*ptr_to_member)( /* arguments */ )

我在Google上找到的随机链接有更多信息:http://www.goingware.com/tips/member-pointers.html

答案 1 :(得分:3)

为了调用对象的成员函数,您需要提供两件事:

  1. 成员函数的地址,如前所述,您可以通过编写&my_class::my_member
  2. 来获取该函数
  3. 指向要为
  4. 调用成员函数的对象实例的指针(或引用)

    Spirit语义操作希望您提供暴露某个接口的函数或函数对象。在您的情况下,预期的界面是:

    void func(Iterator first, Iterator Last);
    

    其中Iterator是用于调用解析函数的迭代器类型(可通过typename ScannerT::iterator_t访问)。您需要做的是创建一个函数对象,在仍然调用您的成员函数时公开所提到的接口。虽然这可以手动完成,但这样做充其量是乏味的。创建函数对象的最简单方法是使用Boost.Bind:

    prog = (alpha_p >> *alnum_p)
           [
               boost::bind(&ParserActions::do_prog, self.action)
           ];
    

    将为您创建所需的函数对象,绑定和包装您的成员函数。

    所有这些都假设您的成员函数不带任何参数。如果你需要传递这对迭代器,那么语义动作将被调用到你的函数中,构造需要写成:

    prog = (alpha_p >> *alnum_p)
           [
               boost::bind(&ParserActions::do_prog, self.action, _1, _2)
           ];
    

    指示函数对象将其第一个和第二个参数转发给绑定函数。

答案 2 :(得分:1)

函数指针和成员函数指针之间存在根本区别:

  • 必须使用正确类型的参数调用函数指针

  • 必须使用正确类型的对象和正确类型的参数调用成员函数指针。

像对象一样构建成员函数指针不会在指针中注册对象。

如果你想要这样的东西,有各种各样的库这样做(你有一个boost标签,参见bind和信号这样的例子)。