Выполнение определенного кода для каждого вызова метода в C ++ - PullRequest
7 голосов
/ 31 марта 2010

У меня есть класс C ++, который я хочу проверить. Итак, я хотел бы, чтобы все методы печатали свои параметры и возвращались, как раз перед тем, как выйти.

Последний выглядит несколько легко. Если я вернусь () для всего, макрос

#define return(a) cout << (a) << endl; return (a)

сделал бы это (может быть неправильно), если бы я падронизировал все возвраты в скобки (или как там это может называться) Если я хочу снять это, просто закомментируйте определение.

Однако печатные материалы кажутся более сложными. Есть ли способ, которым я могу сделать это, используя структуры C ++ или с трудолюбивым взломом?

Ответы [ 6 ]

8 голосов
/ 31 марта 2010

На ум приходит несколько вариантов:

  • Используйте отладчик.
  • Используйте шаблон декоратора , как предложено Space_C0wb0y. Тем не менее, это может быть много ручного набора текста, так как вам придется дублировать все методы в украшенном классе и добавить запись самостоятельно. Возможно, вы могли бы автоматизировать создание объекта декоратора, запустив doxygen в вашем классе и затем проанализировав его вывод ...
  • Используйте аспектно-ориентированное программирование . (Ведение журнала - это то, что вы хотите сделать, это обычное применение AOP.) Википедия перечисляет несколько реализаций AOP для C ++: AspectC ++ , XWeaver и FeatureC ++ .
4 голосов
/ 31 марта 2010

Однако печатные материалы кажутся более сложно. Есть ли способ, которым я могу это сделать, используя структуры C ++ или с Workaroud взломать?

номер


Обновление: Я потеряю некоторую краткость в своем ответе, предположив, что вы, вероятно, сможете достичь того, что вам нужно, применив Design by Contract .

2 голосов
/ 31 марта 2010

Если вы не против вставить код вручную, вы можете создать класс, который:

  1. записывает запись в метод в конструкторе
  2. предоставляет метод для сброса произвольных параметров
  3. предоставляет метод для записи статуса
  4. выход логов с записанным статусом в деструкторе

Использование будет выглядеть примерно так:

unsigned long long
factorial(unsigned long long n) {
    Inspector inspect("factorial", __FILE__, __LINE__);
    inspect.parameter("n", n);
    if (n < 2) {
        return inspect.result(1);
    }
    return inspect.result(n * fact(n-1));
}

Конечно, вы можете писать макросы для объявления инспектора и проверки параметров. Если вы работаете с компилятором, который поддерживает макросы списка переменных аргументов, вы можете получить результат, похожий на:

unsigned long long
factorial(unsigned long long n) {
    INJECT_INSPECTOR(n);
    if (n < 2) {
        return INSPECT_RETURN(1);
    }
    return INSPECT_RETURN(n * fact(n-1));
}

Я не уверен, что вы можете получить более чистое решение, не переходя на что-то вроде среды AOP или какого-либо специального инструмента генерации кода.

2 голосов
/ 31 марта 2010

Похоже, вы хотите использовать для меня утилиту отладки. Это позволит вам увидеть все параметры, которые вы хотите.

1 голос
/ 31 марта 2010

Если все ваши методы virtual, вы можете использовать pattern-decorator-pattern для достижения этого очень элегантным способом.

РЕДАКТИРОВАТЬ: Из вашего комментария выше (вы хотите вывод для статистики) Я пришел к выводу, что вы обязательно должны использовать шаблон decorator. Он предназначен для такого рода вещей.

0 голосов
/ 31 марта 2010

Я бы просто использовал библиотеку журналов (или некоторые макросы) и вставлял вызовы журналов вручную. Если в вашем классе нет чрезмерного количества методов, вероятно, быстрее освоиться, чем разрабатывать и отлаживать более сложные решения.

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