代码之家  ›  专栏  ›  技术社区  ›  Jacob

指向成员函数的函数指针

  •  2
  • Jacob  · 技术社区  · 14 年前

    这里有几个重复项,但是没有人解释为什么我可以使用一个成员变量来存储指针(在 FOO )但是当我用一个局部变量(在 BAR ),这是违法的。有人能解释一下吗?

    #include <iostream>
    using namespace std;
    
    class FOO
    {
    public:
     int (FOO::*fptr)(int a, int b);
     int add_stuff(int a, int b)
     {
      return a+b;
     }
     void call_adder(int a, int b)
     {  
      fptr = &FOO::add_stuff;
      cout<<(this->*fptr)(a,b)<<endl;
     }
    };
    
    class BAR
    {
    public:
     int add_stuff(int a, int b)
     {
      return a+b;
     }
     void call_adder(int a, int b)
     {  
      //int (BAR::*fptr)(int a, int b);
      //fptr = &BAR::add_stuff;
      //cout<<(*fptr)(a,b)<<endl;
     }
    };
    
    int main()
    {
     FOO test;
     test.call_adder(10,20);
     return 0;
    }
    
    5 回复  |  直到 14 年前
        1
  •  7
  •   Billy ONeal IS4    14 年前

    当使用成员函数指针时,需要指定它所作用的对象。

    也就是说,你需要创建一个指向bar实例的指针(我们称之为 bar ):

    (bar->*fptr)(a,b)
    

    要调用函数或bar实例并执行以下操作:

    (bar.*fptr)(a,b)
    

    换一种说法:

    #include <iostream>
    
    class BAR
    {
        int i;
    public:
        BAR(): i(0) {};
        int AddOne() { return ++i; };
        int GetI() { return i; };
    }
    
    int main()
    {
        BAR bar;
        auto fPtr = &BAR::AddOne; // This line is C++0x only (because of auto)
        std::cout << (bar.*fPtr)(); //This will print 1 to the console
        std::cout << std::endl;
        std::cout << bar.GetI(); //This will also print 1 to the console.
    }
    
        2
  •  8
  •   AnT stands with Russia    14 年前

    显然,你误解了 this->* 在召唤中 FOO .

    当你使用 这个& gt;* 与成员 fptr 指针 这个& gt;* 部分与此无关 FPTR 加入 . 当使用指向成员的指针调用成员函数时,必须使用 ->* 操作员(或) .* 接线员)和你 总是 必须指定要与指向成员的指针一起使用的实际对象。这就是 这个& gt;* 调用表达式的一部分。也就是说,电话会 总是 看起来像

    (<pointer-to-object> ->* <pointer-to-member>) (<arguments>)
    

    或作为

    (<object> .* <pointer-to-member>) (<arguments>)
    

    呼叫的左边( <pointer-to-object> <object> 以上)不能省略。

    换句话说,是否 FPTR 是成员变量、局部变量、全局变量或任何其他类型的变量,调用 FPTR 总是 看起来像

    (this->*fptr)(a, b);
    

    假设您想用 *this 对象。如果,在另一个例子中,您想为指针指向的其他对象调用它 pfoo ,呼叫将如下所示

    FOO *pfoo;
    ...
    (pfoo->*fptr)(a, b);
    

    在你 BAR 类调用的外观应为 (this->*fptr)(a,b) 尽管 FPTR 是局部变量。

        3
  •  2
  •   Fyodor Soikin    14 年前

    我不认为变量本身的使用是非法的。非法的是试图在没有类实例的情况下调用该方法。

    也就是说,你真的应该打电话 (someVar->*fptr)(a,b) 哪里 someVar 属于类型 BAR*

        4
  •  1
  •   John Dibling    14 年前

    BAR::call_adder() 有几个问题。其中一个,你在混合箱子。在C++中,CASE是有意义的。 BAR bar 不一样。其次,在修复了case问题之后,您可以标记并分配指针,但是当您试图通过指针调用成员函数时,需要使用 operator ->* 有一个类对象。这里是 call_adder() 固定的

     void call_adder(int a, int b)
     {  
      int (BAR::*fptr)(int a, int b);
      fptr = &BAR::add_stuff;
      cout<<(this->*fptr)(a,b)<<endl;
     }
    
        5
  •  0
  •   Jay    14 年前

    当您调用一个类的成员函数时,编译器会在函数运行时生成设置“this”的代码。当您从未完成的函数指针调用它时。有很多方法可以解决这个问题,但它们不能“保证”工作,而且依赖于编译器。只要你小心,知道你可能遇到的问题,你就可以做到。