![]() |
когда нужно поддержать несколько конструкторов из базового класса... Пару лет назад я столкнулся с ситуацией, в которой получалась не очень красивая структура кода. Пришлось подумать и улучшением её, и сейчас я хочу поделиться своим решением. Если эта проблема уже имеет известное решение, дайте ссылку. Будет интересно сравнить со своим решением. Итак, задача: имеем класс с несколькими конструкторами, с различными комбинациями параметров (т.е. несколько возможностей инизиализации объектов), и при наследовании от этого класса нужно, чтобы конструкторы наследника поддерживали все эти параметры, т.е. все варианты инициализации предка: Code: class B Для решения этой проблемы я выделил инициализационные параметры в отдельную структуру и все конструкторы заменил одним, которому передаётся эта структура (более того, для удобства инициализации этой структуры конструкторы B перемещаются в неё): Code: class B Code: class D: public class B 1. Число параметров конструктора класса D зависит от количества предков (как прямых, в результате множественного наследования, так и косвенных, пришедших через цепочку наследований). Изменения в иерархии будут приводить к изменениям в сигнатуре конструктора, поэтому желательно перейти к конструктору с одним параметром. 2. Полученная схема не даёт возможности инициализировать по умолчанию часть базовых классов или часть членов (как базовых классов, так и нижнего класса). 3. Если каждая структура InitData повторяет члены соответствующего класса (в большинстве случаев так и будет), то можно ли избежать этой дубликации? 1. Первая проблема решается объединением всех структур InitData в одну: Code: class D: public class B1, public class B2 2. Проблему инициализации по умолчанию некторых предков или членов можно решить двумя путями. В тех случаях, когда каждому члену InitData соответствует член в соответствующем классе, можно просто инициализировать эти члены в InitData по умолчанию. В частности, если вся структура инициализирована по умолчанию, то это будет соответствовать вызову конструктора по умолчанию для соответствующего класса, и тогда конструктор B::B(const InitData& d = InitData()) полностью вытеснит конструктор по умолчанию. В остальных же случаях в структуры InitData придётся добавить специальное поле, указывающее, какие члены инициализированы нормальными данными. 3. Дублирования членов можно избежать, если каждый класс будет унаследован от своих инициализационных данных. При этом потребуется виртуальное наследование: Code: struct BData |
All times are GMT. The time now is 18:56. |
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.