How to use the correct instance with static inline member pointer and static member function?

116 Views Asked by At

I have a static callback member function that calls a non-static window procedure member function via a static inline pointer. The problem is, it ends up calling the last instance. Here is an example that demonstrates the core of the problem:

#include <iostream>

struct A {
    static inline A* pThis;
    int i;     

    A(int i) : i(i) {
        pThis = this;
    }

    static void foo() {
        std::cout << pThis->i << std::endl;
    }
};

int main() {
    A a1(1); 
    A a2(2); 

    a1.foo(); // prints 2 instead of 1
    a2.foo(); // prints 2 as expected

    return 0;
}

Note, I cannot change the signature of the callback function, so recommending to make foo accept an argument is futile. How do I solve this problem?

2

There are 2 best solutions below

0
user12002570 On BEST ANSWER

The problem is, it ends up calling the last instance

Each time you're creating an object using the ctor A::A(int) you're updating pThis to point to the current/latest instance. Thus when you create a2 using A a2(2);, the pThis was updated to point to this new object.

This looks more like a design problem than a programming problem.

0
Jarod42 On

Correct "static callback member" have a way to pass extra argument,

The old/C way is generally a void* userData. In C++, std::function would be a good alternative, or an "interface".

as A::foo is static,

a1.foo(); is actually a1; A::foo(); so just A::Foo();.

Changing the callback would be fine.

I cannot change the signature of the callback function

So, if you want to reset A::pThis to "correct" one, you might do it manually:

A::pThis = a1;
A::foo();
A::pThis = a2;
A::foo();