2

这有几个重复,但没有人解释为什么我可以使用成员变量来存储指针(在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;
}
4

5 回答 5

8

显然,您误解了this->*in call in的含义FOO

当您this->*与成员fptr指针一起使用时,该this->*部分与fptr成为FOO. 当您使用指向成员的指针调用成员函数时,您必须使用->*运算符(或.*运算符),并且您始终必须指定要与指向成员的指针一起使用的实际对象。这就是this->*调用表达式的部分所做的。即电话将永远看起来像

(<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

于 2010-04-30T16:12:54.710 回答
7

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

即您需要创建一个指向 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.
}
于 2010-04-30T16:03:44.153 回答
2

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

也就是说,你真的应该调用(someVar->*fptr)(a,b)where someVaris 类型BAR*

于 2010-04-30T16:05:54.020 回答
1

BAR::call_adder()有几个问题。一方面,你在混合案例。在 C++ 中,大小写很重要。 BAR并且bar不一样。其次,在修复案例问题后,您对指针进行了贴标和分配,但是当您尝试通过指向成员函数的指针调用时,您需要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;
 }
于 2010-04-30T16:10:59.223 回答
0

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

于 2010-04-30T16:57:33.447 回答