我对成员函数调用的指针有问题。函数指针调用之外的指针“this”的地址与调用内部的地址不同,因此对类变量的所有访问都会导致错误的值。
我在这里包含代码。
class ClassInterface
{
public:
ClassInterface(void);
~ClassInterface(void);
};
class ClassA:public ClassInterface
{
public:
float _a;
public:
ClassA(void);
~ClassA(void);
virtual void Update();
};
class ClassB:public ClassA
{
public:
ClassB(void);
~ClassB(void);
void Update();
void ProcessTaskB(void*);
};
//ClassB.CPP
void ClassB::ProcessTaskB(void*)
{
printf("ClassB::ProcessTaskB\n");
printf("Address of myB INSIDE callback = %d\n",this);
_a += 100;
}
//test CPP
#include "stdafx.h"
#include "ClassInterface.h"
#include "ClassA.h"
#include "ClassB.h"
typedef void (ClassInterface::*Callback) (void* );
int _tmain(int argc, _TCHAR* argv[])
{
ClassA* myA = new ClassA();
ClassB* myB = new ClassB();
Callback fptrB = (Callback) &(ClassB::ProcessTaskB);
printf("Address of myB outside callback = %d\n",myB);
(myB->*fptrB)(NULL);
return 0;
}
这是输出:
Address of myB OUTSIDE callback = 1332696
Address of myB INSIDE callback = 1332700
因此声明_a + = 100;不会改变_a。它改变了地址(& _a + 4)。
我无法解决这个问题。请帮我解决。
答案 0 :(得分:1)
在您更新的表单中,您的代码完全正确并且没有任何问题。对于不正确行为的唯一解释是您必须在某些"限制"中使用MSVC ++编译器。成员指针模型(一般情况下工作不正确)。实际上,我相信当您尝试转换成员指针时,MSVC ++编译器会发出相应的警告。你刚才忽略了警告吗?
无论如何,添加
#pragma pointers_to_members( full_generality, virtual_inheritance )
为了启用C ++标准所要求的成员函数指针的完整功能,您需要编写代码,并且您的代码应该可以正常工作。在你的情况下这
#pragma pointers_to_members( full_generality, multiple_inheritance )
应该足够了。 /vmm, /vms, /vmv
组与/vmg
组合的编译器选项可以达到同样的效果。
此外,在这种情况下避免使用C风格的演员表。您使用的转化由static_cast
Callback fptrB = static_cast<Callback>(&ClassB::ProcessTaskB);
另外,请勿尝试在%d
中使用printf
格式说明符打印指针。这是另一种未定义的行为。打印指针是%p
格式说明符的用途。