头common.h
向前声明的类的成员函数指针Test
和功能接收一个成员函数指针:向前声明的类
class Test;
void func(const Test &t, int (Test::*f)() const, int x, int y);
在源文件target.cpp
,我定义函数,使得
#include "common.h"
void func(const Test &t, int (Test::*f)() const, int x, int y) {
std::cout << "f: " << (t.*f)() << ", x: " << x << ", y: " << y << std::endl;
}
在我的主文件中,我定义了类Test
并使用函数func
:
class Test {
public:
int example() const { return 1; }
};
#include "common.h"
int main() {
Test t;
func(t, &Test::example, 0xaaaaaaaa, 0xbbbbbbbb);
return 0;
}
显然这有点臭,因为指向成员函数的指针有时不仅仅是一个简单的指针。但由此产生的行为有点压倒性:给定的参数0xaaaaaaaa
和0xbbbbbbbb
将不会正确传递给函数。或者更确切地说,功能func
解释给定的堆栈不同于调用者将数据压入堆栈。 f
的大小取决于该类是只是前向声明还是实际定义的。与Visual Studio 2013编译的输出是:
f: 1, x: 0, y: 2130567168
我想,如果一个向前声明就足够了,它真的不要紧是否有给予与否的定义。
“0xaaaaaaaa”和“0xbbbbbbbb”不能表示为“int”(在windows调用约定下,请参见[MSDN](http://msdn.microsoft.com/zh-cn/library/296az74e.aspx))。缩小转换调用未定义的行为。您是否尝试过使用较小的数字? – Mankarse
我选择这些值是为了在我的堆栈中清楚地看到它们。当然,如果您选择较小的值,它也不起作用。我认为,缩小是在编译期间完成的,因为这些值是文字并且绑定到整数值。 – phlipsy
恕我直言,它是不正确的,因为这个函数可能是虚拟或不虚拟 – borisbn