頭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