在业余时间(作为学习练习),我一直致力于在 C++ 中创建一些模板化容器和分配器,类似于标准模板库中提供的那些。
到目前为止,我制作的容器是单链表、双链表、堆栈和队列。Stack 和 Queue 都使用单链表作为它们的内部结构,因为我存储了头指针和尾指针。
现在是我的第一个分配器类,池分配器。在内部,它使用我的 Stack 对象之一来获取和释放预分配的对象。我现在想将此池分配器与我的单链表和双链表结合使用,以便预先分配存储数据的内部节点对象。在我看来,现在这样在我的项目中创建了一个循环依赖问题。
我在非模板类上解决此类依赖问题的常规方法通常涉及前向声明、指针和将实现拆分为 cpp 文件。问题似乎出现了,因为我无法将模板代码声明和实现拆分为各自的 .h 和 .cpp 文件。
一些代码供进一步参考:
单链表.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
}
};
堆栈.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();
}
};
池分配器.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
}
};
我有点不确定解决这个问题的最佳方法。我能想到的唯一方法是让池分配器不使用我的任何容器类。我想我可以创建一个分配器类独有的内部链表类,但这似乎是不必要的代码重复。
如果有人对此有任何见解,我将很高兴听到。我希望我足够彻底地涵盖了所有内容并提供了一个可接受的代码示例。如果有任何缺失的信息,请告诉我。提前致谢。