В свободное время (в качестве учебного упражнения) я работал над созданием шаблонов и распределителей на языке C++, аналогичных тем, которые были предоставлены как часть стандартной библиотеки шаблонов.Циркулярная зависимость класса шаблонов C++
Пока что контейнеры, которые я изготовил, представляют собой единый связанный список, двойной связанный список, стек и очередь. Стек и Очередь используют единый связанный список как свою внутреннюю структуру, так как я храню указатели на голове и хвосте.
Теперь наступает мой первый класс распределителя, пул-распределитель. Внутри он использует один из моих объектов Stack для получения и освобождения предварительно выделенных объектов. Теперь я хотел бы использовать этот Pool Allocator в сочетании с моим Singlely Linked List и Doubly Linked List, чтобы предварительно выделить внутренние объекты Node, которые хранят данные. Мне кажется, что теперь это создает проблему круговой зависимости в моем проекте.
Мой обычный метод решения проблем зависимостей, подобных этому в не-шаблонных классах, обычно включает в себя форвардные объявления, указатели и разделение реализации в файл cpp. Проблема, похоже, возникает из-за того, что я не могу разделить объявления и реализации кода шаблона в свои файлы .h и .cpp.
Некоторый код для дальнейшего использования:
SinglyLinkedList.h:
#include "PoolAllocator.h" //Adding this line creates a compile error
template<typename T> class SinglyLinkedList
{
private:
Node<T> *_Head, *_Tail;
public:
void PushFront(T *obj)
{
//Allocate new node object and set it as _Head
}
void PushBack(T *obj)
{
//Allocate new node object and set it as _Tail
}
T *PopFront()
{
//Remove _Head and return node data
}
};
Stack.h:
#include "SinglyLinkedList.h"
template<typename T> class Stack
{
private:
SinglyLinkedList<T> _List;
public:
void Push(T *obj)
{
_List.PushFront(obj);
}
T *Pop()
{
return _List.PopFront();
}
};
PoolAllocator.h:
#include "Stack.h"
template<typename T> class PoolAllocator
{
private:
Stack<T> _Pool;
public:
void Initialize(unsigned int capacity)
{
//Dynamically allocate a bunch of T and push them onto _Pool
}
T *Acquire()
{
//Remove an item from _Pool and return it
}
void Release(T *obj)
{
//Push the object back onto the _Pool
}
void Dispose()
{
//Free all memory from _Pool
}
};
Я бит неуверен в лучшем пути к solv e этот вопрос. Единственный способ, которым я могу думать, это сделать, чтобы Pool Allocator не использовал ни один из моих классов контейнеров. Я полагаю, что я мог бы создать внутренний связанный класс списка, который является исключительным для класса распределителя, но это похоже на ненужное дублирование кода.
Если у кого-то есть понимание, я был бы очень рад это услышать. Надеюсь, я достаточно тщательно рассмотрел и предоставил приемлемый пример кода. Если есть какая-либо недостающая информация, пожалуйста, дайте мне знать. Заранее спасибо.
Возможный дубликат [Разрешение круговой зависимости между классами шаблонов] (http://stackoverflow.com/questions/3353831/resolving-a-circular-dependency-between-template-classes) –
Я забыл поставить защитники заголовка в мой пример, но они есть. Я также пробовал эту ссылку без везения :( –
Даже если бы вы могли ее скомпилировать, я не вижу, как это будет работать - чтобы заполнить 'Stack' внутри' PoolAllocator', вы нажимаете на него вещи, которые вызывает 'List.PushBack()', который должен был бы перейти к неинициализированному «PoolAllocator», чтобы получить память, не так ли? –