Название: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 12, 2015, 22:45 Хочу выстрелить в ногу и никак не получается, хотя вроде с++.
Задача - просто при создании объекта выводить - Enter to class %nameOfClass. (Чтобы не было дурных вопросов, это парсинг файла, нужно для дебага). Ну нету решений, нету не то что красивых решений, нету тупо никаких. 1 вариант - самый плохой. Использовать TypeInfo (пусть в нашем случае QObject). Отбросим оверхед. Так для каждого класса поди используй Q_OBJECT. Промахнулся(забыл написать или ещё чего) и теперь ищи что глючит - то ли твой основной код, то ли код, который дебаг пишет. На тестовый код ещё тестовый код писать. 2 вариант - тупо в каждом конструкторе писать логирование. Не вижу отличие от 1-го варианта. 3 теоретический вариант (невозможен, зато идеален) - чисто виртуальная функция с именем класса. При создании класса компилятор тебя пошлет подальше, если её не определил. Но, как известно, виртуальная функция в конструкторе не вызывается (вызываются при определённых условиях, они нам не подходят). Итог. Получается вот что - пишешь описание класса, и каким то образом говоришь (даже себе через некоторое время) - читай описание! И при использование класса то там нужно подковырнуть, то там нужно подковырнуть. Может я в стену упёрлся и не вижу простого решения? А теперь собственно вопрос. Как выводить информацию из конструктора для определённого класса и при этом!!!!! знать, что ты не забыл определить эту информацию. Название: Re: Конструктор и лог Отправлено: m_ax от Сентябрь 12, 2015, 23:24 Надуманная проблема. К тому же едва ли поможет при отладке..
Но как вариант: Код
Название: Re: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 12, 2015, 23:41 Надуманная проблема. К тому же едва ли поможет при отладке.. Но как вариант: Код
Надуманная проблема? Гм. Нет слов. В чем её надуманость. Вы представте себе код, основной. И код, который ещё перегружен #ifdef для юнит тестов. В чём для вас надумманость? Ну как вам сказать. Ну вот собрались куча гуру, мол взламать пароль к серверу пентагона. А тут кто-то вскакиват и говорит - будем использовать перебор паролей! Название: Re: Конструктор и лог Отправлено: m_ax от Сентябрь 12, 2015, 23:55 Цитировать Гм. Нет слов. В чем её надуманость. Цитировать Как выводить информацию из конструктора для определённого класса и при этом!!!!! знать, что ты не забыл определить эту информацию. Во-вторых, Цитировать Ну вот собрались куча гуру, мол взламать пароль к серверу пентагона. знаете, думаю для гуру тратить своё время на форуме, задавая подобные вопросы (Как выводить информацию из конструктора для определённого класса) - это последнее, что пришло бы им в голову :)А тут кто-то вскакиват и говорит - будем использовать перебор паролей! Не, я, конечно, за всех гуру не отвечаю, это просто моё имхо) Название: Re: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 13, 2015, 00:21 Не, я, конечно, за всех гуру не отвечаю, это просто моё имхо) Вы видно задачу не поняли, поэтому сводите всё к тому, что это возможно. Я же вам говорил совершенно про другое - про "не напряжно". Название: Re: Конструктор и лог Отправлено: m_ax от Сентябрь 13, 2015, 00:33 Цитировать Тогда зачем вы потратили свое время на данный опус? Ну так я же не говорю, что я гуру) И потом кто из нас эту тему начал?)Цитировать Я же вам говорил совершенно про другое - про "не напряжно". Что для вас "не напряжно"? Я так понимаю, вставить одну строчку в конструктор Код это напряжно? А вдруг забудем?) Чтож дальше будет? :) Название: Re: Конструктор и лог Отправлено: Bepec от Сентябрь 13, 2015, 00:50 Красивого решения нет.
И вам предложили все простые варианты :) Название: Re: Конструктор и лог Отправлено: Igors от Сентябрь 13, 2015, 07:06 Как выводить информацию из конструктора для определённого класса и при этом!!!!! знать, что ты не забыл определить эту информацию. Выводить - макрушник в духе Q_OBJECT. "Не забыть" - придется лепить что-то типа RegisterClass, который отсыпет ошибку компиляции если нет макрушника. Ну и на стартеКод
Название: Re: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 13, 2015, 11:37 Спасибо за предоставленные решения. Значит буду в "лоб" писать и исчезнет чувство, что может быть по другому.
Название: Re: Конструктор и лог Отправлено: Igors от Сентябрь 13, 2015, 13:06 Цитировать Я же вам говорил совершенно про другое - про "не напряжно". Что для вас "не напряжно"? Я так понимаю, вставить одну строчку в конструктор Код это напряжно? А вдруг забудем?) Чтож дальше будет? :) Конечно невозможно запретить написать класс "без этого", таких средств нет в языке. Но лучше как-то так Код
Код Впрочем это уже по Вашей части :) Название: Re: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 13, 2015, 13:45 Легковесный подход - "невставка" ничем не грозит, а надо чтобы отливалась в ошибки компиляции. Да и конструкторов может быть не один, или вообще не быть. А еще конструкторы копирования и перемещения. И уже с десятком классов забот хватает. Конечно невозможно запретить написать класс "без этого", таких средств нет в языке. Но лучше как-то так Код
Код Впрочем это уже по Вашей части :) Слишком, слишком сложно. Ведь это не основной код, вспомогательный. Тут ещё вылазит проблема иерархии классов. Классов много, действительно, они просты и примитивны, но, в тоже время есть промежуточные, которые во всей иерархии напрямую не вызываются (наследуются). Тут ведь в чем вопрос. В основном коде (если так можно выразиться) мы может контроллировать ситуацию и применять какие то правила. Юнит тестами мы выравнимаем ситуацию, если что-то пропустили. Но контролировать её ещё и в дополнительном коде (который использует юнит тест)..... Так на юнит тест я ещё буду писать юнит тест. Сама задача не важна, но приведу вам пример, чтобы поняли глубину, так сказать. Парсинг С++ файла. Не компиляция, а просто синтаксический разбор. И вот вы находите if, создаётся класс, который отвечает за парсинг if.... Вообщем классическая нисходящая рекурсия. Т.е. классов много. И жизнь у них очень мала. Название: Re: Конструктор и лог Отправлено: m_ax от Сентябрь 13, 2015, 14:03 Цитировать Да и конструкторов может быть не один, или вообще не быть. А еще конструкторы копирования и перемещения. И уже с десятком классов забот хватает. Ну да, согласен..Цитировать Впрочем это уже по Вашей части :) Тогда уж можно и без всяких шаблонов:Код
Цитировать Тут ещё вылазит проблема иерархии классов. Классов много, действительно, они просты и примитивны, но, в тоже время есть промежуточные, которые во всей иерархии напрямую не вызываются (наследуются). Не, сейчас о наследовании речи не идёт. Макрос "инстанцирует" в ваш класс этакого логгера, который при конструировании будет делать, что вы ему скажете..Цитировать И вот вы находите if, создаётся класс, который отвечает за парсинг if.... Вообщем классическая нисходящая рекурсия. Т.е. классов много. И жизнь у них очень мала. С этого момента лучше поподробнее)Название: Re: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 13, 2015, 14:28 Не, сейчас о наследовании речи не идёт. Макрос "инстанцирует" в ваш класс этакого логгера, который при конструировании будет делать, что вы ему скажете.. Т.е. именно проблема в наследовании и проявляется. При создании класса (далее я под созданием класса имею в виду создание объекта класса) выводить нам нужно имя базового класса? Нет конечно. А если базовый класс не промежуточный и тоже может участвовать в работе? Вывод содержимого "Enter to class Name1" и сразу "Enter to class Name2" что означает? Что мы вызвали базовый класс или класс запустил новый? Если уж по аналогии с if - то он может запустить класс ParseBoolCondition, либо наследоваться от фиг значет чего. А вывод всегда один и тот же. Я надеюсь внятно описал, т.к. очень запутано изъясняюсь. И вот вы находите if, создаётся класс, который отвечает за парсинг if.... Вообщем классическая нисходящая рекурсия. Т.е. классов много. И жизнь у них очень мала. Цитировать С этого момента лучше поподробнее) Ну, это не та задача, которую следует в данном топике обсуждать. Я её для примера привёл. Я так понимаю, тема вам интересна, но обсуждение её заведёт в дебри. Название: Re: Конструктор и лог Отправлено: m_ax от Сентябрь 13, 2015, 14:46 Цитировать Агаг. Проблема начинает вылазить, когда нам нужно решать, в какой класс записывать лог, в какой нет. Ну это тож решается.. Если я правильно понял, то вы хотите как то так:Т.е. именно проблема в наследовании и проявляется. При создании класса (далее я под созданием класса имею в виду создание объекта класса) выводить нам нужно имя базового класса? Нет конечно. А если базовый класс не промежуточный и тоже может участвовать в работе? Вывод содержимого "Enter to class Name1" и сразу "Enter to class Name2" что означает? Что мы вызвали базовый класс или класс запустил новый? Код Это в принципе можно сделать.. Цитировать Я так понимаю, тема вам интересна, но обсуждение её заведёт в дебри. Ну как бы это сказать.. Не то чтобы интересна, просто меня всегда настораживают конструкции if-else-switch в коде, которые превращают его в спагетти код.. Возможно, есть решение более изящьнее.. Но да, это заведёт нас в дебри околоархитектурных вопросов и рукомаханий, которые здесь не особо любят) Собственно, я по этому и спросил) Название: Re: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 13, 2015, 14:52 Ну это тож решается.. Если я правильно понял, то вы хотите как то так: Код
Это опять же усложнение, проще придерживаться правил. Тем более, REMOVE_LOG(base) - мыслей нет, что там может быть. Не важно, не говорите, что там можно реализовать, это не имеет значение, т.к. усложняет всё. Цитировать Ну как бы это сказать.. Не то чтобы интересна, просто меня всегда настораживают конструкции if-else-switch в коде, которые превращают его в спагетти код.. Возможно, есть решение более изящьнее.. Но да, это заведёт нас в дебри околоархитектурных вопросов и рукомаханий, которые здесь не особо любят) Собственно, я по этому и спросил) При чём здесь спагетти в коде при парсинге кода? Нам дано, что дано и все варианты нужно отработать. Тем более, я не парсю с++, я парсю MIB, приводил для примера. Название: Re: Конструктор и лог Отправлено: m_ax от Сентябрь 13, 2015, 14:55 Цитировать При чём здесь спагетти в коде при парсинге кода? Нам дано, что дано и все варианты нужно отработать. Ну как причём:Цитировать И вот вы находите if, создаётся класс, который отвечает за парсинг if.... Вообщем классическая нисходящая рекурсия. Т.е. классов много. И жизнь у них очень мала. Ладно, забейте) Сегодня всё-таки праздник :) Название: Re: Конструктор и лог Отправлено: Igors от Сентябрь 13, 2015, 15:28 Слишком, слишком сложно. Ну это жалкие крохи по сравнению с тем во что разворачивается Q_OBJECT, а против него Вы почему-то не возражаете :) Может по аналогии стоит сделать упор на краткость использования (прицепил макрос и все), а служебный класс (задаваемый этим макросом) развивать всяко-разно.Ведь это не основной код, вспомогательный. Агаг. Проблема начинает вылазить, когда нам нужно решать, в какой класс записывать лог, в какой нет. А почему это нет? С какой стати это скрывать? Не вижу для этого никаких оснований, лог должен содержать полную инфуТ.е. именно проблема в наследовании и проявляется. При создании класса (далее я под созданием класса имею в виду создание объекта класса) выводить нам нужно имя базового класса? Нет конечно. А вот интересно как определить логируемый класс или нет - учитывая что он может наследоваться от логируемого? Сходу не сообразю, m_ax, как там с "магией"? :) Название: Re: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 13, 2015, 15:37 Ну это жалкие крохи по сравнению с тем во что разворачивается Q_OBJECT, а против него Вы почему-то не возражаете :) Может по аналогии стоит сделать упор на краткость использования (прицепил макрос и все), а служебный класс (задаваемый этим макросом) развивать всяко-разно. Этот вариант я и принял.Цитировать Агаг. Проблема начинает вылазить, когда нам нужно решать, в какой класс записывать лог, в какой нет. Т.е. именно проблема в наследовании и проявляется. При создании класса (далее я под созданием класса имею в виду создание объекта класса) выводить нам нужно имя базового класса? Нет конечно. Цитировать А почему это нет? С какой стати это скрывать? Не вижу для этого никаких оснований, лог должен содержать полную инфу Потому что не будет разницы, между наследованием и вызовов класса.Я уже об этом писал выше. Повторюсь - "Enter to class Name1" и "Enter to class Name2". Вопрос - класс Name1 вызван наследуюемым конструктором (Name2) или класс Name1 вызвал Name2? А вот интересно как определить логируемый класс или нет - учитывая что он может наследоваться от логируемого? Сходу не сообразю, m_ax, как там с "магией"? :) [/quote] Название: Re: Конструктор и лог Отправлено: m_ax от Сентябрь 13, 2015, 15:43 Цитировать А вот интересно как определить логируемый класс или нет - учитывая что он может наследоваться от логируемого? Сходу не сообразю, m_ax, как там с "магией"? Ну я бы курил в сторону SFINE http://habrahabr.ru/post/205772/ (http://habrahabr.ru/post/205772/)Название: Re: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 13, 2015, 15:48 Цитировать А вот интересно как определить логируемый класс или нет - учитывая что он может наследоваться от логируемого? Сходу не сообразю, m_ax, как там с "магией"? Ну я бы курил в сторону SFINE http://habrahabr.ru/post/205772/ (http://habrahabr.ru/post/205772/)Вместо одной проблемы создаются десяток других. Нет уж, я лучше "листик на монитор навешу". Для меня тема закрыта, засим откланиваюсь. Все остальные решения в разы сложнее. Название: Re: Конструктор и лог Отправлено: m_ax от Сентябрь 13, 2015, 15:58 Цитировать Вместо одной проблемы создаются десяток других. Ну дык я и не вам это предлагаю) Название: Re: Конструктор и лог Отправлено: Igors от Сентябрь 14, 2015, 08:57 Потому что не будет разницы, между наследованием и вызовов класса. По правилам языка нельзя обойти конструктор базового класса, поэтому последовательность Name1, Name2 всегда означает конструктор Name2.Я уже об этом писал выше. Повторюсь - "Enter to class Name1" и "Enter to class Name2". Вопрос - класс Name1 вызван наследуюемым конструктором (Name2) или класс Name1 вызвал Name2? Вместо одной проблемы создаются десяток других. Ну а нервничать зачем? Ах, не оказалось быстрого, удобного решения (как из ассыстента), расстроился :) Так это нормально. А задумка совсем неплохая. Вот только как бы ее "расширить". Печать в конструкторе (кстати почему и не в деструкторе тоже?) - ну иногда полезна, но может и засыпать консоль (если будут контейнеры). Есть смысл печатать (по запросу) число "живых" объектов такого-то типа, отслеживая порядковый номер и.т.д. Ну да ладно, не хотите обсуждать - не надо.Нет уж, я лучше "листик на монитор навешу". Для меня тема закрыта, засим откланиваюсь. Все остальные решения в разы сложнее. Название: Re: Конструктор и лог Отправлено: AzazelloAV от Сентябрь 19, 2015, 14:15 Цитировать По правилам языка нельзя обойти конструктор базового класса, поэтому последовательность Name1, Name2 всегда означает конструктор Name2. Нельзя, но это не будет обозначать, что это наследуемый вызов. Это может быть вызов конструктора из конструктора (не наследуемого, а new что-то новое), что введёт в заблуждение при исследовании лога. Тут только один выход - промежуточные (базовые) классы не должны ничего выводить, что уже определенныё на нас ограничения накладывает - нельзя использовать непосредственно базовый класс, все вызывающие классы должны быть "листьями дерева". Цитировать Ну а нервничать зачем? Ах, не оказалось быстрого, удобного решения (как из ассыстента), расстроился :) Так это нормально. А задумка совсем неплохая. Вот только как бы ее "расширить". Печать в конструкторе (кстати почему и не в деструкторе тоже?) - ну иногда полезна, но может и засыпать консоль (если будут контейнеры). Есть смысл печатать (по запросу) число "живых" объектов такого-то типа, отслеживая порядковый номер и.т.д. Ну да ладно, не хотите обсуждать - не надо. Нельзя переходить на личности. При чем здесь ассистант? и нервы здесь нипричём. Почему про деструктор изначально промолчал? Конечно, нужно выход из деструктора логировать. Но это зеркальное отображение конструктора, так что разницу не вижу. Тем более, деструктор виртуальный (это нам мало поможет, если с конструктором не разобрались). Нет, я хочу обсуждать, почему, просто был в отпуске, вот и всё. Также про оверхед Q_OBJECT (спрашивали выше) - нету тут оверхеда, потому как есть логи, которые могут анализировать пользователи, а есть логи, которые только для дебага. Поэтому наследование от QObject + макрос Q_OBJECT как оверхед для дебажной версии (пусть хоть в 10 раз) меня не очень беспокоит. Цитировать Есть смысл печатать (по запросу) число "живых" объектов такого-то типа, отслеживая порядковый номер и.т.д. Ну да ладно, не хотите обсуждать - не надо. Тут от задачи зависит, мне такое не подходит. Мне нужна визуализация последовательности вызовов. Ну а консоль не засорится, просто нужно добавить лишний ifdef, вывод то такой не всегда нужен, а в случает глубокой отладки. Также хочу отбросить инсинуации "тут что-то не так и ты не правильно проектируешь классы". Это синтаксический разбор файла, и иерархия классов (наследование), и иерархия объектов (принадлежность) может быть какой угодной и пересекаться по сотни раз с друг другом во всех случаях. Для меня лично выход из этой ситуации (если использовать системный подход) - это Q_OBJECT, где мы можем наворотить что угодно - и про забывчивость и все остальное. Но пока очень лениво, может когда будет уровень ошибки такой, что займусь этой задачей. Пока не буду распыляться. Тем более, чтобы сделать это решение универсальным, для будущих решений, нужно потратить не мало времени (ну неделю точно с тестированием всяким), чего не хочется. Только не говорите, что неделя много. |