对于我的一个类(class),我正在编写一个程序,该程序将使用模板化内存池结构来处理类的新实例的分配,同时将它们保持在一起。目前声明如下:
template<typename T, unsigned int N>
class MemoryPool
{
//Stuff
};
其中 T
是为其创建此池的类,N
是池中可以放置的最大元素数。我想为创建的类型重载 new
,以便在合理的情况下更轻松地与池进行交互——但我不确定是否合理。
目前,我的想法是,如果可以在 MemoryPool
中重载 new
作为 T
的友元函数,那么 应该 从那里可行,但我不确定。而且,我不确定开始设置它的最佳方法。我已经尝试了几种不同的方法来声明重载的 new
,但我什至在实现它之前就遇到了错误。
- 这是确保
new
被任何使用MemoryPool
的类覆盖的合理方法吗? - 这样做有可能吗?
- 这样做是个好主意吗?
- 如何设置函数声明来完成此操作?
以防万一,我使用的是 Visual Studio 2010。
请注意,模板的具体使用和重载 new
不是家庭作业的一部分。如果可能的话,这就是我想要实现它的方式,以便将来更容易阅读作业的其余部分。所以,如果没有合理的方法,我只是使用 MemoryPool
中的成员函数来实现相同的目标。
谢谢!
示例实现:
MemoryPool<Object, MAX_OBJECTS> objectPool; //Pool to store objects
Object* allObjects[MAX_OBJECTS]; //Locations of objects
//Make a new object (this is how I'd like to do it)
allObjects[0] = new Object(/*args*/);
//(If I can't do the above, this would be the alternative)
allObjects[0] = objectPool.AllocateNewSlot();
allObjects[0]->Initialize(/*args*/);
在这个例子中,MemoryPool
的使用负责 new
的实际实现,确保对象是在它的池中而不是堆上的任何地方创建的(以确保所有对象都位于一个集中的、更可控的位置。
最佳答案
可以重载 new 运算符,但我建议不要这样做。
我认为你走错了方向。您不想隐藏事情并让用户不确定发生了什么。在这种情况下,您应该明确表示您正在通过池进行分配。
这是您可以执行的操作。
template<typename T, unsigned int N>
class MemoryPool
{
T* malloc()
{
return ... // your pool impl
}
void free(T* ptr)
{
... // your pool impl
}
void destory(T* ptr)
{
ptr->T::~T(); // call destructor
free(ptr);
}
};
int main()
{
MemoryPool<my_class> pool;
my_class* instance = new (pool.malloc()) my_class(/*args*/); // in-place new
return 0;
}
您还应该看看如何 boost pool已实现。
关于c++ - 重载新的 friend 功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4293720/