У вас есть типы Inf1
и Inf2
, которые связаны друг с другом, и по крайней мере один из них содержит абстрактные методы.
Вы хотите вернуть некоторую под-реализацию Inf2
, но какой из них определяется во время выполнения.
Это означает, что вам нужно полиморфизм времени выполнения. Есть три разных способа, которыми вы могли бы приблизиться к этому.
Во-первых, вы можете вернуть указатель - возможно, умный указатель, например unique_ptr
, в общий интерфейс. Для этого требуется свободное хранилище (куча), но становится понятным, и это самый простой ответ.
Во-вторых, вы можете написать объект стирания типа, который предоставляет версию интерфейса Inf2
и пересылает некоторые внутренние детали. Эти внутренние детали в конечном итоге будут использовать интеллектуальный указатель какого-либо типа или третье решение. Преимущество здесь в том, что вы можете скрыть, как вы управляете памятью, и просто выставлять семантику стоимости с дешевым ходом. Недостатком является то, что есть много шаблонов.
В-третьих, вы можете использовать что-то вроде boost::variant
- a union
по набору типов со средствами защиты от доступа к неправильным типам. В то время как boost
не может использоваться напрямую, дизайн может быть имитирован. Идея заключается в том, что у вас есть локальное хранилище, в котором вы размещаете новые данные, кроме, может быть, для более крупных объектов, где вместо этого вы используете смарт-указатель. В отличие от второго решения, набор поддерживаемых типов явно указан в вашем типе. Это самое сложное решение (если у вас нет доступа к boost
) и требует, чтобы у вас было фиксированное (во время компиляции) множество реализаций Inf2
, что все пользователи Inf1
должны иметь полную информацию.
Как уже отмечалось, первое решение является самым простым. Затраты на первое решение основаны только на производительности, и эти результаты производительности не будут трудно исправить после того факта, если вы обнаружите их там, где есть реальные проблемы. Поэтому я бы посоветовал решение №1, а затем профиль, чтобы узнать, слишком ли высокие затраты. Если затраты высоки, перейдите к решению № 3, возможно, в оболочку решения №2.
В чем вы сомневаетесь? Если вы должны использовать Inf2 &, Inf2 * или общий указатель? – bennofs
'std :: unique_ptr', если вызывающий абонент должен получить право собственности на объект. Действительно, нет (m) каких-либо других вариантов. –
Xeo
@ bennofs Точно, какое бы наименее громоздкое, ясное самое красивое, опрятное решение, которое не заставит меня неприятно смотреть в офис (и нет, мы не используем boost: \ so стандартные решения) – SadStudent