Как я могу проверить, что функция была вызвана другой функцией? - PullRequest
3 голосов
/ 01 июля 2011

В настоящее время я пытаюсь убедиться, что функция-член одного класса только вызывается функцией-членом другого класса.

Архитектура навязана и не может быть изменена,порт означает, что некоторая логика должна быть сделана в a.call() перед вызовом b.call().a.call() поэтому звонит b.call(), чтобы упростить вещи и убедиться, что порядок соблюден.

Я нашел этот ответ на мой вопрос.Проблема только в том, что я использую классы, и эти два класса имеют одинаковое имя функции-члена, и поэтому #define пытается заменить все вхождения, которые имеют разные прототипы.

Ответы [ 5 ]

7 голосов
/ 01 июля 2011

Я рекомендую шаблон пароля .Это очень хорошо для точного контроля над тем, кто что может делать с вашей функцией.

3 голосов
/ 01 июля 2011

Вне моей головы, варианты будут:

  • Сделать b.call личным и сделать b добавить a или a.call как friend
  • Превратите b.call в класс и поместите тело в приватный конструктор с a или a.call как friend
  • grep исходного кода для b.call, убедитесь, что единственный вызов находится в a.call, и добавьте комментарий к объявлению, говорящий "если вы вызовете эту функцию, вас уволят"
  • Измените b.call, чтобы в качестве параметра он принимал хотя бы одно из необходимых ему значений (даже если он игнорирует его и использует значение откуда-то еще)
1 голос
/ 01 июля 2011

Можете ли вы изменить b.call, чтобы взять ссылку на a?Таким образом, b.call сам может вызвать a.call:

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

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

Это гарантирует, что a.call всегда вызывается до выполнения остальной части b.call.

0 голосов
/ 01 июля 2011

Если вы программируете для определенной платформы (например, x86 или x64) и знаете соглашение о вызовах (например, cdecl), то вы можете получить эту информацию из стека

Скажем, вы хотите проверить объект , который вызвал функцию, поэтому используйте указатель this, который помещается в стек перед вызовом функции-члена: получите указатель this и сравните его с объектом, который вы хотите (this_pointer == a)

Если вы хотите проверить определенную функцию, получите адрес вызывающего абонента из стека и проверьте эту функцию: caller_address == A::call. Если это виртуальная функция, используйте указатель this, чтобы получить vtable.

В зависимости от соглашения о вызовах и порядка помещения переменных в стек, вам может понадобиться сначала проверить размеры входных переменных, чтобы получить необходимую информацию.

0 голосов
/ 01 июля 2011

Как насчет использования флага?

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

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

    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...