Запустите код перед каждым вызовом функции для класса В C++

Я хотел бы запустить некоторый код (возможно, функцию) прямо перед каждым вызовом функции для класса и всех функций классов, которые наследуются от этого класса. Я хотел бы сделать это без фактического редактирования каждой функции, возможно ли это вообще?

Я бы согласился на то, чтобы функция вызывалась как первая инструкция каждого вызова функции, а не вызывалась прямо перед этим.

9 ответов


AspectC++ это то, что вы хотите. Сам я им не пользовался, но ... --3-->Аспектно-Ориентированное Программирование paradigm пытается решить эту точную проблему.


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

Это способ реализации IOStreams в STL. Вы можете прочитать больше об этом в C++ Wikibooks.

намерения: чтобы модулировать/рефакторинг часто до и после фрагменты кода (например, инвариант проверка, получение/освобождение блокировок) для всей иерархии классов в одном месте.

с уважением,
Ованес!--1-->


следующее Может быть немного излишним - но как насчет?

http://msdn.microsoft.com/en-us/library/c63a9b7h.aspx


еще одна вещь, которую вы могли бы рассмотреть, - это использование чего-то вроде [boost/C++0X] shared_ptr-оболочки, где вы вызываете свою пользовательскую функцию при перегрузке '- > ' перед возвращением указателя экземпляра класса. Он включает в себя изменение использования, но не базового класса, и я использовал его пару раз для достижения того же эффекта. Еще одна мысль.


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


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

например:

class Base {
  public:
    void MyMethod(void) { /* Insert code here */ YourMethod(); }
  protected:
    virtual void YourMethod(void) {}
};

если разработчик знает, что у него есть определенный подкласс, он все равно может обойти ваш код, просто используя dynamic_cast и используя его собственный метод. Таким образом, вы можете следовать другим уже опубликованным предложениям, которые не связаны с базовым языком C++.


Это похоже на то, что делает профилировщик. Вы смотрели на источник для каких-либо инструментов профилирования?


вы также можете сделать это с помощью любопытно повторяющийся шаблон шаблона (CRTP).


используя g++, вы можете использовать опцию -pg для соответствующих единиц компиляции, что заставляет компилятор генерировать вызов функции mcount в начале каждой функции. mcount обычно предоставляется инструментами профилирования, такими как gprof, но вы также можете реализовать себя. Однако вы должны убедиться, что

  • mcount имеет связь C (и не является искаженным именем в стиле C++), т. е. путем реализации его как функции C и компиляции с чистым C компилятор как gcc.
  • единица компиляции, содержащей mcount не компилируется с -pg.