Я думаю, что ваша настоящая проблема в том, что вы связали две вещи: базовый класс Checker и некоторый механизм регистрации (производных) экземпляров Check.
Между прочим, это не особенно надежно: я могу использовать ваши классы Checker, но я могу захотеть зарегистрировать их по-другому.
Может быть, вы могли бы сделать что-то вроде этого: Checker получит защищенный ctor (в любом случае, он абстрактный, и поэтому только проверенные классы должны вызывать ctor Checker).
Производные классы также имеют защищенные ctors и открытый статический метод («именованный шаблон конструктора») для создания экземпляров. Этот метод создает новости для подкласса Checker, и они передают его (полностью созданный на этом этапе) в класс CheckerRegister (который также является абстрактным, поэтому пользователи могут реализовать свои собственные, если это необходимо).
Вы используете любой одиночный шаблон или механизм внедрения зависимостей, который предпочитаете, чтобы создать экземпляр Checker и сделать его доступным для подклассов Checker.
Один простой способ сделать это - использовать статический метод getCheckerRegister в Checker.
Так что подкласс Checker может выглядеть так:
class CheckBufferOverrun: public Check {
защищенный:
CheckBufferOverrun: Check («Проверка границ») {
// поскольку у каждого производного есть имя, почему бы просто не передать его как аргумент?
}
общественности:
CheckBufferOverrun makeCheckBufferOverrun () {
CheckBufferOverrun that = new CheckBufferOverrun ();
// get the singleton, pass it something fully constructed
Checker.getCheckerRegister.register(that) ;
return that;
}
Если это выглядит так, что это будет много шаблонного кода, напишите шаблон. Если вы беспокоитесь об этом, поскольку каждый экземпляр шаблона в C ++ является реальным и уникальным классом, напишите базовый класс без шаблонов, который будет регистрировать любой производный от Checker.