指向函数调用的指针vs指向成员函数调用的指针



我一直想知道为什么调用指向函数的指针与调用指向成员函数的指针在使用取消引用操作符*(即

)方面存在风格差异。
void(*fptr)()=&f; // pointer to function f()
fptr(); // call f() via pointer to function
Foo foo; // instance of Foo
void (Foo::*fptr)()=&Foo::f; // pointer to member function f()
(foo.*fptr)(); // call foo.f() via pointer to member function

在第一部分中,您不使用*操作符通过函数指针调用f(),但是必须在通过指针(foo.*fptr)()调用成员函数时使用它。为什么会有这种差异?为什么不直接使用(foo.fptr)()来保持一致性?有什么深刻的原因吗?或者这就是c++的设计方式?

我将引用c++常识中的内容。相关章节的标题是指向成员函数的指针不是指针。作者解释了为什么指向成员函数的指针不能被实现为指向函数的指针。我将使用这个(它们是不同的东西的事实)作为不同语法的理由:

当你取非静态成员函数的地址时,你不会得到地址;你得到一个指向成员函数的指针。

(…)

与指向数据成员的指针一样,为了解引用指向成员函数的指针,需要对象或指向对象的指针。(…)在指向成员函数的指针的情况下,我们需要对象的地址作为(或计算)this指针的值用于函数调用,也可能用于其他原因。

请注意,没有"虚拟"之类的东西。指向成员函数的指针。虚性是成员函数本身的属性,而不是指向它的指针的属性。

这就是为什么通常不能将指向成员函数的指针实现为指向函数的简单指针的原因之一。成员函数指针的实现必须在自身内部存储有关其所指向的成员函数是还是非虚的信息,关于在哪里可以找到合适的虚函数表指针的信息,关于在函数的this指针上加或减的偏移量,以及可能的其他信息。指向成员函数的指针通常实现为包含该信息的小结构体,尽管许多其他实现也在使用。

解引用和调用指向成员函数的指针通常涉及检查存储的信息,并有条件地执行适当的虚函数或非虚函数调用序列

我认为,考虑到这些差异,可以证明语法的差异是合理的,尽管历史的设计选择可能发挥了它们的作用。

如果我们简单地使用foo。在Fptr中,它与我们调用成员函数的方式相同,使编译器变得复杂。实际上,fftr不是foo的成员函数。因此*fptr显示了差异。也许编译可以实现这一点,我认为这就是现在c++的设计方式。

最新更新