有几个副本,但没有人解释为什么我可以使用成员变量来存储指针(在FOO
中),但当我尝试使用局部变量时(在{{1}的注释部分) }),这是非法的。有人可以解释一下吗?
BAR
答案 0 :(得分:8)
显然,你在this->*
的电话中误解了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
。
答案 1 :(得分: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.
}
答案 2 :(得分:2)
我不认为变量本身的使用是非法的。在没有类实例的情况下尝试调用该方法是非法的。
也就是说,您应该真正致电(someVar->*fptr)(a,b)
其中someVar
类型为BAR*
答案 3 :(得分:1)
BAR::call_adder()
有几个问题。首先,你是混合案例。在C ++中,案例很有意义。 BAR
和bar
不一样。其次,在修复了案例问题之后,您已经decalred并指定了指针,但是当您尝试通过指向成员函数的指针调用时,您需要将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;
}
答案 4 :(得分:0)
当您调用类的成员函数时,编译器会生成代码以在函数运行时设置“this”。从未完成的函数指针调用它时。有办法绕过它,但它们不能“保证”工作并且依赖于编译器。只要你小心并且知道可能遇到的问题,你就可以做到。