How can I check a function was called by another f

2019-07-02 02:48发布

I am currently trying to make sure that a member function of one class is only called by a member function of another class.

The architecture is imposed and cannot be changed, the port means that some logic has to be done in a.call() before calling b.call(). a.call() therefore calls b.call() to simplify things and make sure the order is respected.

I found this answer to my question. Only, the problem is that I am using classes, and the two classes have the same member function name and so the #define tries to replace all the occurrences which have different prototypes.

5条回答
唯我独甜
2楼-- · 2019-07-02 03:26

Can you change b.call to take a reference to a? This way, b.call can call a.call itself:

struct A {
    void call() {
        // do stuff
    }
};

struct B {
    void call(A & a) {
        a.call();
        // do stuff
    }
};

This makes sure that a.call is always called before the rest of b.call is executed.

查看更多
▲ chillily
3楼-- · 2019-07-02 03:28

I recommend the passkey pattern. It's very good for giving fine grained control on who can do what with your function.

查看更多
何必那么认真
4楼-- · 2019-07-02 03:36

Off the top of my head, options would be:

  • Make b.call private and make b add a or a.call as a friend
  • Turn b.call into a class and put the body into a a private constructor with a or a.call as a friend
  • grep the source code for b.call, make sure the only call is in a.call, and add a comment at the declaration saying "if you call this function you will be fired"
  • Change b.call to take at least one of the values it needs as a parameter (even if it ignores it and uses the value from somewhere else)
查看更多
Rolldiameter
5楼-- · 2019-07-02 03:44

How about using a flag?

a.call()
{
    // ...
    flag = 1;
    b.call();
    flag = 0;
}

b.call()
{
    if (flag == 0)
        return;

    // ...
}
查看更多
乱世女痞
6楼-- · 2019-07-02 03:47

If you program for certain platform (say x86 or x64), and you know the calling convention (e.g. cdecl), then you can get this info from the stack

Say you want to check the object that called the function, so use the this pointer that is pushed to the stack prior to calling the member function: get the this pointer and compare it with the object that you want (this_pointer == a)

If you want to check certain function, get the caller address from the stack and check against that function: caller_address == A::call. If it's a virtual function, use the this pointer to get the vtable.

Depending on the calling-convention and the order of pushing variables on the stack, you may have to check first the input variables sizes, in order to get to the information you need.

查看更多
登录 后发表回答