重载新的朋友功能?

时间:2010-11-27 20:22:49

标签: c++ visual-studio-2010 operator-overloading memory-management

对于我的一个类,我正在编写一个程序,该程序将使用模板化的内存池结构来处理类的新实例的分配,同时将它们保持在一起。目前声明如下:

template<typename T, unsigned int N>
class MemoryPool
{
    //Stuff
};

其中T是要为其创建此池的类,N是可以放置在池中的最大元素数。我想为创建的类型重载new以使得与池的交互更容易,如果它是合理的事情 - 但我不确定它是否。

我现在的想法是,如果可以将new作为T中的MemoryPool的朋友函数重载,那么应该可以从那里开始但我不确定。并且,我不确定开始设置它的最佳方式。我尝试了几种不同的方法来声明重载的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的实际实现,确保在池中创建Object而不是堆上的任何位置(以确保所有对象都是在一个集中的,更可控的位置。

1 个答案:

答案 0 :(得分:2)

可能会使新运算符超载,但我建议不要这样做。

我认为你的方向是错误的。你不想隐藏东西,让用户不确定发生了什么。在这种情况下,您应该明确表示您是通过池分配的。

这是你能做的。

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的实施方式。