1

AFAIK,在 C++ 中,在同一类的函数成员中调用另一个成员函数不应该需要“this”前缀,因为它是隐式的。但是,在使用函数指针的特定情况下,编译器需要它。只有当我通过 func 指针包含调用的“this”前缀时,以下代码才能正确编译 -

当使用函数指针时,编译器可以推断出它指向同一类的成员函数吗?

class FooBar 
{
private: 
    int foo;

public:  

    FooBar()
    {
        foo = 100;
    }

    int GetDiff(int bar)
    {
        return abs(foo - bar);
    }

    typedef int(FooBar::*MyFuncPtr)(int); 

    void FooBar::Bar()
    {       
        MyFuncPtr f = &FooBar::GetDiff;
        (this->*f)(10);
        GetDiff(10);
    }

};
4

5 回答 5

6

这是必需的,因为成员函数指针(与函数指针不同)没有绑定,您可以将它们与不同的对象一起使用。

(this->*f)(10);
(foo.*f)(10);
// etc.
于 2012-06-26T17:10:32.830 回答
2

当您调用实例成员函数时,this 指针被隐式地放入函数参数中。因此,您还需要在this通过函数指针调用该函数时指定。

f不是类的成员,而是局部变量,您也可以指定另一个实例指针而不是this,因此编译器无法推断。成员函数指针与类成员变量相同。

于 2012-06-26T17:11:34.157 回答
1

一个简单的问题是,这是一个语言设计的问题,而语言就是这样设计的。

在成员函数内部,并且为了在编译器遇到标识符时简化通用语法,它会从此类(加上参数上的 ADL)开始执行查找,并且如果查找找到此类型的明确非静态成员(或基类型)然后编译器将为您注入this->(即应用于operator->指针this)。

在指向成员的指针的情况下,过程是完全不同的。通过查找找到指针(实际上不是指针,而是为了参数),但您有责任提供将在其上调用它的对象并使用适当的运算符(.*用于调用指向成员的指针在引用上,或->*在指针上调用成员)。

请注意,被调用的运算符是不同的,并且过程完全不同(在一种情况下查找找到一个成员,在另一种情况下它找到一个恰好是指向成员的变量),但最重要的部分是调用指向成员的指针的频率不够高,而且调用它们的this频率更低,以至于它不能保证对小用例的语法进行豁免。

于 2012-06-26T18:04:05.143 回答
0

发生这种情况是因为 C++ 运行时在您不查看时处理类的方式。基本上将函数指针存储在实例中是低效的,因此编译器使用函数指针构建一个特定于类的表,这些函数指针与您定义的成员函数具有相同的数量,并且在运行时传递 this 指针(AFAIK visualc 传递通过 ecx 的指针,我不完全确定 GCC 上会发生什么)

所以基本上当你这样做时

instance->foo(10);

您告诉运行时使用参数 10 调用函数 foo 并将(实例)作为 this 指针传递,这就是为什么您必须明确说明必须调用哪个对象的原因。

于 2012-06-26T17:26:50.577 回答
0

f不是 的成员FooBar。所以如果你想调用f的一个实例FooBar,你必须告诉它是哪个实例。

在您的示例中,f确实包含FooBar 的成员,但编译器不知道。

于 2012-06-26T17:09:46.047 回答