Я делал нечто подобное, но с использованием шаблонов.
Моей задачей было написание класса настроек с сериализацией в реестр или в файл.
Поля класса (структуры) я описывал при помощи шаблонных объектов-оболочек с общим базовым
интерфейсом (для хранения в общем списке).
При этом класс-оболочка вел себя как «умный» указатель, то есть имитировал стандартный синтаксис доступа к членам структуры.
В примитивном виде это было как-то так:
template<typename T>
class CValue : public IValue
{...};
class CMyStruct
{
public:
CValue<int> id;
CValue<std::string> name;
private:
std::vector<IValue*> m_values;
};
Каждый объект CValue в своем конструкторе регистрирует себя в общем списке m_values.
После чего список m_values можно использовать для обхода объектов с целью сравнения или сериализации (шаблон визитор).
1. Где вы вообще увидели MFC, и что за претензии к использованию C++11 в 2012 году?
2. std::set в примере, т.к. мне нужно было написать пример быстро и по сути (оригинальный код я показать не могу).
В оригинале у меня std::map с хитрым составным ключом, включающим в себя type_info + строчку.
Таким образом, что результатом поиска может быть только объект определенного типа (так же, как и в примере с std::set). Единственное отличие при использовании std::map это то, что я могу добавлять в контейнер любое количество объектов разного типа с нулевым ID (как и в примере), и несколько объектов одного типа с разными ID:
>>Если вы в данном контексте знаете конкретный класс, зачем его конструировать через фабрику?
Клиентский код может иметь доступ к декларации класса, но при этом не уметь его конструировать.
Конечно, все зависит от конкретной ситуации, я просто делал нечто подобное и вспомнил об этом.
Пример того, что я делал см. ниже.
Что Вы будете делать в случае, если создаваемому объекту понадобится некий параметр при конструировании?
Как по мне, то регистрировать стоит не конечный класс, а его билдер, либо уже созданный объект класса с клонированием (прототип).
Еще, при необходимости, можно сделать шаблонный метод для конструирования классов конкретного типа (не базового). Это позволит в некоторых случаях избежать нежелательной конвертации к классу-наследнику.
Я использовал похожую конструкцию как IoC контейнер, но там у меня хранились объекты разных классов без общего предка (по принципу boost::any).
У нас был случай на работе: сотруднику пришла пустая коробка с Kindle Keyboard 3G.
Устройство вытянули где-то в аэропорту, разодрав боковину коробки, при этом отрывная полоска была цела. В итоге амазон бесплатно отправил еще одно устройство, но впечатление было испорчено…
Мне кажется, что не совсем корректно говорить о 2010 студии, т.к. как минимум представления типов работают и в 2005 студии тоже.
Я так понял что Вы проверяли Ваши надстройки только для 2010 студии, а для более ранних поленились?
Вывод в консоль или в файл влияет на работу программ.
Например, многопоточные программы в некоторых случаях могут продолжать работать при включенных логах, но начинают падать при отключении логирования.
Без отладчика можно только предполагать что делает программа, под отладчиком — видеть как программа выполняется. Особенно, если эта программа не покрыта юнит-тестами, или взаимодействует с другими программами.
Отладчик в ряде случаев просто незаменим:
* Отладка приложений при загрузке/выгрузке системы с использованием ядерного отладчика (сервисы, boot-time приложения (autochk.exe), драйвера).
* Анализ креш-дампов.
Какой смысл не использовать готовый, надежный инструмент в пользу наколенных решений в виде логов?
С интересом проводить время это конечно хорошо, но реальность такова, что приходится всю жизнь горбатиться чтобы купить 1-комнатную квартиру в Москве/Киеве.
Да никакой магии нет, notepad.exe не заморачивается (так же как и большинство других программ) и ведет себя простым образом, то есть запускается с правами администратора, и все окна, а также дочерние процессы, создаваемые в нем, наследуют эти права.
Explorer.exe спроектирован по другому, он стремится всегда быть запущенным с минимальными правами и предоставлять разширенные права по мере надобности.
Только что провел интересный эксперимент — под лимитированным пользователем прибил процесс explorer.exe, а затем запустил его от имени администратора и получил shell, запущенный от админа, но после того, как я попытался запустить explorer как файловый менеджер, то получил еще один экземпляр процесса с лимитированными правами.
В общем намутили они с этим explorer-ом, а вот с блокнотом все предельно ясно, и нет там никакой магии.
Драйвера на C проще, т.к. есть готовые декларации функций, поставляемые с WDK.
На другом языке программирования Вам пришлось писать декларации импортируемых функций вручную, и вручную же гарантировать их корректность.
Кстати, стоит упомянуть еще о статическом анализаторе PREFast, который заточен под C.
Сегодня маркетологи Киевстара взорвали мне мозг следующей записью:
«Тарификация… звонков… является посекундной и осуществляется в первую секунду каждой минуты разговора, секунды со второй по шестидесятую каждой минуты разговора не тарифицируются.»
Моей задачей было написание класса настроек с сериализацией в реестр или в файл.
Поля класса (структуры) я описывал при помощи шаблонных объектов-оболочек с общим базовым
интерфейсом (для хранения в общем списке).
При этом класс-оболочка вел себя как «умный» указатель, то есть имитировал стандартный синтаксис доступа к членам структуры.
В примитивном виде это было как-то так:
Каждый объект CValue в своем конструкторе регистрирует себя в общем списке m_values.
После чего список m_values можно использовать для обхода объектов с целью сравнения или сериализации (шаблон визитор).
В итоге получилась довольно интересная штуковина.
Этот код перегружен синтаксисом ЯП, также нарушена инкапсуляция, т.к. наружу торчит реализация:
2. std::set в примере, т.к. мне нужно было написать пример быстро и по сути (оригинальный код я показать не могу).
В оригинале у меня std::map с хитрым составным ключом, включающим в себя type_info + строчку.
Таким образом, что результатом поиска может быть только объект определенного типа (так же, как и в примере с std::set). Единственное отличие при использовании std::map это то, что я могу добавлять в контейнер любое количество объектов разного типа с нулевым ID (как и в примере), и несколько объектов одного типа с разными ID:
В общем, оригинальный пример мне показался перегруженным и я сократил его до std::set.
3. type_info::berofre() возвращает int, а не bool.
Этот код хорош, потому что он простой:
И этот код смотрится хорошо:
Но вариант с лямбда функциями просто ужасен:
Клиентский код может иметь доступ к декларации класса, но при этом не уметь его конструировать.
Конечно, все зависит от конкретной ситуации, я просто делал нечто подобное и вспомнил об этом.
Пример того, что я делал см. ниже.
Как по мне, то регистрировать стоит не конечный класс, а его билдер, либо уже созданный объект класса с клонированием (прототип).
Еще, при необходимости, можно сделать шаблонный метод для конструирования классов конкретного типа (не базового). Это позволит в некоторых случаях избежать нежелательной конвертации к классу-наследнику.
Я использовал похожую конструкцию как IoC контейнер, но там у меня хранились объекты разных классов без общего предка (по принципу boost::any).
Устройство вытянули где-то в аэропорту, разодрав боковину коробки, при этом отрывная полоска была цела. В итоге амазон бесплатно отправил еще одно устройство, но впечатление было испорчено…
Я так понял что Вы проверяли Ваши надстройки только для 2010 студии, а для более ранних поленились?
Например, многопоточные программы в некоторых случаях могут продолжать работать при включенных логах, но начинают падать при отключении логирования.
Отладчик в ряде случаев просто незаменим:
* Отладка приложений при загрузке/выгрузке системы с использованием ядерного отладчика (сервисы, boot-time приложения (autochk.exe), драйвера).
* Анализ креш-дампов.
Какой смысл не использовать готовый, надежный инструмент в пользу наколенных решений в виде логов?
Вы не правы, C++ успешно используется для написания драйверов.
1) Перегрузить глобальные операторы new/delete:
2) Не пользоваться глобальными объектами или реализовать initterm/atexit для вызова конструкторов/деструкторов глобальных объектов;
3) Использовать C++ по минимуму (мы не использовали С++ exceptions и сторонние библиотеки, даже STL)
Да никакой магии нет, notepad.exe не заморачивается (так же как и большинство других программ) и ведет себя простым образом, то есть запускается с правами администратора, и все окна, а также дочерние процессы, создаваемые в нем, наследуют эти права.
Explorer.exe спроектирован по другому, он стремится всегда быть запущенным с минимальными правами и предоставлять разширенные права по мере надобности.
Только что провел интересный эксперимент — под лимитированным пользователем прибил процесс explorer.exe, а затем запустил его от имени администратора и получил shell, запущенный от админа, но после того, как я попытался запустить explorer как файловый менеджер, то получил еще один экземпляр процесса с лимитированными правами.
В общем намутили они с этим explorer-ом, а вот с блокнотом все предельно ясно, и нет там никакой магии.
На другом языке программирования Вам пришлось писать декларации импортируемых функций вручную, и вручную же гарантировать их корректность.
Кстати, стоит упомянуть еще о статическом анализаторе PREFast, который заточен под C.
«Тарификация… звонков… является посекундной и осуществляется в первую секунду каждой минуты разговора, секунды со второй по шестидесятую каждой минуты разговора не тарифицируются.»