Страницы

Поиск по вопросам

понедельник, 9 марта 2020 г.

Узнать имя класса во время исполнения программы

#cpp #boost


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

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

Это можно реализовать? Можно и boost`ом.
    


Ответы

Ответ 1



Функция typeid(object) возвращает объект типа type_info с информацией о типе объекта, для которого она вызывается (собственно, о классе). У этого объекта(type_info) есть метод name(), который и возвращает имя класса. Для использования нужно подключить . Так что в итоге для получения имени класса нужно использовать typeid(*this).name() Или, если функция не является методом класса, передать в typeid сам объект или разыменованный указатель.

Ответ 2



Собственные средства c++ не позволяют ничего узнать о контектсте вызова функции. Стек вызова можно проанализировать с помощью некоторых внешних библиотек / API операционной системы. Например: http://man7.org/linux/man-pages/man3/backtrace.3.html https://msdn.microsoft.com/en-us/library/ms680650%28VS.85%29.aspx . Но для применение этих средств может налагать дополнительные ограничения на собираемый код (сборка с отладочной информацией и т.д.). Более разумно, ИМХО, передавать контекст вызова явно: это позволит использовать "штатные" средства c++: __FILE__, __LINE__, __func__, .... Извлечение контекста можно замаскировать макросом: struct Context{ const char* file; unsigned line; const char* function; }; // Work around MSVS #ifndef __func__ #define __func__ __FUNCTION__ #endif #define CONTEXT() Context({ __FILE__, __LINE__, __func__}) void foo( int a, int b, Context c ); #define FOO(a, b) foo( a, b, CONTEXT() ) Имя класса можно извлечь либо разобрав имя __FUNCTION__, либо из указателя this : typeid(this).name() Но не хочется включать этот обращение к this в макрос, поскольку функции может быть вызвана из контекста, статической функции. С другой стороны для целей разделения логов может быть достаточно __FILE__.

Комментариев нет:

Отправить комментарий