У меня есть этот существующий код, где у них есть класс и метод инициализации в этом классе. Ожидается, что, как только объект класса будет создан, им нужно вызвать initialize для него.
Причина, по которой существует метод initialize . Объект создается раньше, чтобы иметь глобальную область видимости, а затем метод initialize вызывается позже после загрузки библиотеки DLL, от которой он зависит.
Проблема с инициализацией У класса теперь есть этот bool isInitialized, который нужно проверять в каждом методе, прежде чем он продолжит работу и возвращает ошибку, если он не инициализирован. Проще говоря, это большая боль.
Одно из возможных решений Инициализация в конструкторе. Есть только указатель на объект в глобальной области видимости. Создайте реальный объект после загрузки DLL.
Проблема с вышеупомянутым решением Любой, кто создает объект этого класса, должен знать, что его нужно создавать только после загрузки dll, иначе он потерпит неудачу.
Это приемлемо?
call_once
в C ++ 11 . Проекты, которые еще не находятся на C ++ 11, должны изучить, как call_once реализован в C ++ 11 (сосредоточиться на том, какую проблему он решает, а затем как), а затем повторно реализовать его в своем (устаревшем) варианте C ++. Он нуждается в многопоточном безопасном примитиве синхронизации, состояние которого необходимо статически инициализировать (с постоянным значением). Обратите внимание, что компиляторы до C ++ 11 могут иметь другие особенности, которые должны быть выполнены.Ответы:
Похоже, работа для виртуального прокси.
Вы можете создать виртуальный прокси, содержащий ссылку на рассматриваемый объект. Хотя библиотека DLL не загружена, прокси-сервер может предлагать клиентам определенное поведение по умолчанию, после загрузки библиотеки DLL прокси просто перенаправит все запросы реальному субъекту.
Виртуальный прокси-сервер будет отвечать за проверку инициализации DLL и на основании этого решает, следует ли делегировать запрос реальному субъекту.
Шаблон прокси в Википедии
Как вам эта идея?
источник
Ничего полезного не происходит, если DLL еще не загружена; объект только генерирует ошибку. Это фатальная ошибка? Как обрабатывается ошибка?
Ваша методология тестирования гарантирует, что эта ошибка никогда не возникает в готовом продукте?
Это похоже на работу для тестирования, а не для архитектурного дизайна. Не просто вернуть ошибку,
assert
чтобы она никогда не случалась.Исправьте все клиенты класса, которые в настоящее время отлавливают и игнорируют ошибку, чтобы не пытаться вызвать ее в первую очередь.
Многопоточным шаблоном может быть установка переменной общего условия после загрузки библиотеки DLL, а конструктор объекта ожидает (и блокирует другие потоки) до загрузки библиотеки DLL.
источник
Первое: избегайте глобальных объектов как вредителей, если их состояние никогда не изменяется (конфигурация).
Теперь, если вы застряли с этим, по каким-то причинам, есть несколько проектов, которые могут вам помочь.
Я пришел с двумя идеями:
Используйте Фасад, чтобы загрузить DLL. Доступ к Объекту возможен только через Фасад, Фасад загружает DLL при создании и создает экземпляр Объекта одновременно.
Используй прокси, но умный вид;)
Позвольте мне остановиться на втором пункте, так как я боюсь, что ответ @edalorzo , возможно, напугал вас:
Теперь у вас есть только один чек.
Это также можно сделать с помощью умного указателя:
Здесь вы только резервируете место для указателя, изначально нулевого, и только когда DLL загружена, вы фактически выделите объект. Все предыдущие обращения должны вызывать исключение (NullException: p?) Или завершать программу (чисто).
источник
Это сложный вопрос. Я чувствую, что архитектура может помочь с проблемой.
Из доказательств, похоже, что .dll не загружается при загрузке программы. Это звучит почти как плагин.
Одна вещь, которая приходит на ум, это то, что вам нужно инициализировать .dll. Программист должен предположить, что объект не будет надежно возвращаться в любом случае. Возможно, вы сможете воспользоваться этим (
bool isObjectLoaded() { return isInitialized; }
), но вы обязательно получите больше отчетов об ошибках по вашим проверкам.Я думал о синглтоне.
Если вы вызываете синглтон, он должен вернуть правильный объект, если он может получить его. Если он не может вернуть правильный объект, вы должны получить некоторое значение ошибки / nullptr / пустой базовый объект. Это не сработает, если объект может умереть от вас.
Также, если вам нужно несколько экземпляров объекта, вы можете использовать что-то вроде Factory.
источник