В течение некоторого времени у меня был шаблон, который упаковывает библиотеку C FILE *. Это довольно классическая реализация общего указателя на класс-оболочку для ФАЙЛА *. Причина использования моего собственного общего указателя заключается в том, чтобы предоставить бесплатные замены функций для некоторых свободных функций FILE * из библиотеки C, чтобы я мог выполнить замену устаревшего кода, который работает с FILE *.
.
Реализация, которая у меня есть, использует внутреннюю оболочку, которая гарантирует, что при ее удалении собственный FILE * будет закрыт. RAII.
Однако я столкнулся с необходимостью создать аналогичную систему для обработки случая, когда я хочу, чтобы базовый ФАЙЛ * был сброшен и обрезан, а не закрыт, когда уничтожен последний держатель ФАЙЛА *. То есть у меня есть открытый файл FILE * исходного типа с гарантированным закрытием, но я хочу передать неизвестную копию файла FILE * другому объекту, который будет гарантировать, что при уничтожении его последнего экземпляра он будет сбрасывать и обрезать ФАЙЛ *, а не закрывать его, поэтому я оставлю базовый ФАЙЛ * в открытом состоянии, но с содержимым потока, сброшенным на диск (и размер файла, отражающий только допустимое содержимое).
Я решил это тривиально для полиморфизма времени компиляции. Но мне нужен какой-то способ для обеспечения полиморфизма во время выполнения, и я действительно не хочу помещать еще один слой косвенности в этот сценарий (то есть, если я использовал полиморфный указатель либо на автоматическое закрытие, либо на автоматическую очистку ФАЙЛА * обертка, я был бы золотым - но я действительно хочу сохранить ту же глубину, что и сейчас, и скрыть полиморфизм внутри реализации пользовательского общего указателя).
В основном, если у меня есть:
template <class WrapperT>
class FilePointerT
{
public:
// omitted: create, destroy, manipulate the underlying wrappered FILE*
private:
WrapperT * m_pFileWrapper;
ReferenceCount m_rc;
}
Очевидно, тонны деталей опущены. Достаточно сказать, что когда последний из этих объектов удаляется, он удаляет последний m_pFileWrapper (фактически, если бы я переписывал этот код, я бы, вероятно, использовал boost :: shared_ptr).
Несмотря на это, реальная проблема здесь в том, что я нахожусь в тупике о том, как получить FilePointerT , чей WrapperT может варьироваться, но затем может использоваться в коде, как если бы они все были одинаковыми (что, в конце концов, они поскольку реализация WrapperT не имеет никакого влияния на структуру и интерфейс FilePointerT (по сути, pimpl).
Что я могу объявить, что может содержать любой FilePointerT для любого WrapperT?
Или, как я могу изменить определение FilePointerT, чтобы я мог указать конкретный WrapperT?