Незабываемая фабрика: когда создается конструктор? - PullRequest
2 голосов
/ 26 января 2020

Я реализую незабываемую фабрику . Все отлично работает, но одно: классы не регистрируются, иногда.

Я думаю, что ключевой частью является Registrar::registered член. Если он используется, «Действительно забавная часть» вызывает функцию registerT, которая регистрирует класс.

В моем примере с игрушкой класс не зарегистрирован, если только

  1. реализован конструктор (в cpp -файле или в строке). Явный конструктор по умолчанию и наследование конструктора (*) не регистрируют класс.
  2. В базовом классе есть виртуальный метод (Animal), который переопределяется в зарегистрированном классе и реализовано в cpp -файле. Встроенная реализация не работает (в отличие от встроенного ctor).

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

Мой вопрос: При каких обстоятельствах registerT называется ? Другими словами: когда создается экземпляр Registrar? Где я должен поместить (void) registered; таким образом, чтобы он был всегда инстанцирован?

(*), чтобы заставить наследование конструкторов работать, я сделал конструкторы Factory и Factory<...>::Registrar publi c

Редактировать: этот вопрос указал мне на незабываемый пост на заводском блоге . Это не дубликат . Автор этого вопроса, видимо, только забыл добавить «Действительно забавную часть» и решающий почти пустой конструктор. Я не забыл их. Я хочу знать, почему этот важный почти пустой конструктор не создан, хотя он там есть.

Редактировать: Решением было не использовать предложенный образец. Кажется, он не подходит для производственного кода, см. соответствующий вопрос .

1 Ответ

2 голосов
/ 26 января 2020

[basi c .start.dynamic] / 3 A не инициализация odr-use - использование odr (6.2), не вызванное прямо или косвенно инициализацией нелокальной переменной stati c или продолжительности хранения потока.

[basi c .start.dynamic] / 4 Определяется реализацией, будет ли динамическая c инициализация нелокальной не встроенной переменной с помощью stati c Продолжительность хранения упорядочивается до первого оператора main или откладывается. Если оно откладывается, то это происходит до того, как любое использование неинициализации odr любой не встроенной функции или не встроенной переменной, определенной в той же единице перевода, что и инициализируемая переменная.

This это то, что приводит к сбою этой и аналогичных схем саморегистрации. Существует модуль перевода, содержащий определения сущностей, на которые нет ссылок в других местах программы, а только инициализатор переменной stati c, определенной в той же единице перевода. Реализация может решить отложить инициализацию этой переменной stati c до тех пор, пока что-либо в ее единице перевода не будет использовано odr - что никогда не происходит.

...