Address of pointer “this” changed unexpectedly inside a pointer to member function call

感情迁移 提交于 2019-12-25 01:25:43

问题


I have problem with the pointer to member function call. The address of pointer "this" outside the function pointer call is different than inside the call thus all access to the class variables results wrong values.

I include the code here.

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;


}

And this is the output:

Address of myB OUTSIDE callback = 1332696
Address of myB INSIDE callback = 1332700

Thus the statement _a += 100; does not make change to _a. It made change to address (&_a + 4).

I have no clue to resolve this. Please help me fix.


回答1:


In your updated form your code is perfectly correct and has no problems whatsoever. The only explanation for the incorrect behavior is that you must be using MSVC++ compiler in some "restricted" member pointer model (which works incorrectly in general case). In fact, I believe MSVC++ compiler issues the corresponding warnings when you attempt to convert your member pointers. Did you just ignore the warning?

Anyway, add

#pragma pointers_to_members( full_generality, virtual_inheritance )

to you code in order to enable full functionality of member function pointers required by C++ standard, and your code should work fine. In your case this

#pragma pointers_to_members( full_generality, multiple_inheritance )

should be sufficient though. Compiler options from /vmm, /vms, /vmv group in combination with /vmg achieve the same effect.

Also, avoid C-style casts in such contexts. The conversion you are using is performed by static_cast

Callback fptrB = static_cast<Callback>(&ClassB::ProcessTaskB);

Also, don't attempt to print pointers with %d format specifier in printf. This is another undefined behavior right there. Printing pointers is what %p format specifier is for.



来源:https://stackoverflow.com/questions/25221221/address-of-pointer-this-changed-unexpectedly-inside-a-pointer-to-member-functi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!