C++ “指针地址”;这";在指向成员函数调用的指针内意外更改

C++ “指针地址”;这";在指向成员函数调用的指针内意外更改,c++,member-function-pointers,this-pointer,C++,Member Function Pointers,This Pointer,我对成员函数调用的指针有问题。函数指针调用外部的指针“this”的地址与调用内部的不同,因此所有对类变量的访问都会导致错误的值 我在这里包括代码 class ClassInterface { public: ClassInterface(void); ~ClassInterface(void); }; class ClassA:public ClassInterface { public: float _a; public: ClassA(void);

我对成员函数调用的指针有问题。函数指针调用外部的指针“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)


我没有解决这个问题的线索。请帮助我修复。

在更新的表单中,您的代码完全正确,没有任何问题。对错误行为的唯一解释是,您必须在某些“受限”成员指针模型中使用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\u cast

Callback fptrB = static_cast<Callback>(&ClassB::ProcessTaskB);
回调fptrB=static_cast(&ClassB::ProcessTaskB);
另外,不要尝试使用
printf
中的
%d
格式说明符打印指针。这是另一个未定义的行为。打印指针是
%p
格式说明符的用途。

什么是
ClassA
ClassInterface
与任何类的关系如何?
\u a
的声明在哪里?它是一个成员变量吗?静态还是非静态?我刚刚编辑了我的代码。这些都是代码。ClassInterface与任何其他类都不相关,并且_a是ClassAI的一个成员变量,它不一定等同于不同的、不连续的
指针。我们没有展示的代码部分可能存在多重继承。比如说,问题是否表明
ClassInterface
没有V表而
ClassB
有?(虽然在OP提供的代码中并不明显)。@barak manos:问题是由
ClassA
中引入vtable指针引发的。但是,C++标准要求此代码正确工作。为了使其正确工作,OP必须将其编译器从“简化”成员指针支持模式切换到“完全标准”成员指针支持模式。一切都会按预期开始工作。@AndeyT:我试过你的解决方案,但没有成功。地址仍然不同。@user2512031:解决方案是正确的,并且工作正常。您一定把
#pragma
放错地方了。它必须位于最顶端,并且必须在每个文件中可见。无论如何,忘记pragma,最好改为更改全局项目设置。