Der Header common.h
uns auf eine Klasse deklariert Test
und eine Funktion ein Mitglied Funktionszeiger Empfang:Mitglied Funktionszeiger von vorne deklarierten Klasse
class Test;
void func(const Test &t, int (Test::*f)() const, int x, int y);
in der Quelldatei target.cpp
definiere ich die Funktion, so dass
#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;
}
In meiner Hauptdatei definiere ich die Klasse Test
und verwenden Sie die Funktion func
:
class Test {
public:
int example() const { return 1; }
};
#include "common.h"
int main() {
Test t;
func(t, &Test::example, 0xaaaaaaaa, 0xbbbbbbbb);
return 0;
}
Offensichtlich ist dies ein wenig stinkend, da Zeiger auf Elementfunktionen manchmal mehr als ein einfacher Zeiger sind. Aber das resultierende Verhalten ist ein wenig überwältigend: Die angegebenen Parameter 0xaaaaaaaa
und 0xbbbbbbbb
werden nicht korrekt an die Funktion übergeben. Genauer gesagt interpretiert die Funktion func
den gegebenen Stapel anders als die Daten, die der Aufrufer auf den Stapel geschoben hat. Die Größe f
hängt davon ab, ob die Klasse nur vorwärts deklariert oder tatsächlich definiert ist. Die Ausgabe mit Visual Studio erstellt 2013:
f: 1, x: 0, y: 2130567168
Ich dachte, wenn eine Vorwärts-Erklärung ausreicht, ist es wirklich spielt keine Rolle, ob eine Definition gibt es gegeben ist oder nicht.
'0xaaaaaaaa' und' 0xbbbbbbbb' sind nicht als 'int' darstellbar (unter Windows-Aufrufkonventionen, siehe [MSDN] (http://msdn.microsoft.com/en-us/library/296az74e.aspx)). Die einschränkende Konvertierung ruft ein undefiniertes Verhalten hervor. Hast du es mit kleineren Nummern versucht? – Mankarse
Ich wähle diese Werte, um sie klar auf meinem Stack zu sehen. Natürlich funktioniert es auch nicht, wenn Sie kleinere Werte wählen. Und ich dachte, die Eingrenzung wird während der Kompilierung vorgenommen, da diese Werte Literale sind und an ganzzahlige Werte gebunden sind. – phlipsy
IMHO ist es nicht richtig, eine Funktion der forward deklarierten Klasse zu erhalten, da diese Funktion entweder virtuell sein kann oder nicht – borisbn