每个Class类型的静态内存池对象

时间:2014-08-06 15:48:54

标签: c++

我正在尝试为C ++中的类设计基于内存池的分配。目前我有以下运算符重载:

class Foo{

    public:
     Foo(){}

     void* operator new(size_t nbytes, Pool& pool)
     {

         return    pool.alloc(nbytes);
     }

     void operator delete(void* p)
    {

         pool->dealloc(p);   

   }

};

现在,我不想将Pool对象作为参数传递给new.Also我必须以某种方式引用它以便dtor在调用时从它中解除分配。我想在类声明之前将Pool初始化为静态像这样:

   class Foo{

     static boost::pool<> pool ;
     public:
     Foo()
     {

     }

     void* operator new(size_t nbytes)
     {

         return    pool.alloc(nbytes);
     }

     void operator delete(void* p)
    {

         pool.dealloc(p);   

    }


 };

在.cpp中:

    boost::pool<> Foo::pool(sizeof(Foo)) ;//preallocates N * sizeof(Foo) bytes

这是正确的方法吗?&#39;池&#39;总是在Foo的第一个实例创建之前构建?

更新:

这种方法不起作用。当Foo开始创建时,像池一样没有分配内存。

1 个答案:

答案 0 :(得分:3)

在类中声明为static的对象基本上是一个具有滑稽名称的全局对象。全局对象的规则是它们将在main开始之前创建,并在main结束后以未指定的顺序销毁。唯一的保证是,如果特定的编译单元(即.cpp文件)有两个全局对象ABA出现在B之前,那么{{1将在A之前构建。

因此,如果您没有B的任何全局实例,那么一切都没问题,否则您就会遇到问题。

常见的解决方案是使用静态函数返回对本地静态对象的引用,而不是使用全局对象,即

Foo

这解决了这个问题,因为函数内部的静态对象将在第一次调用函数时构造。在这种情况下,您只需要注意多线程(即,如果存在两个线程同时进入静态函数的风险)。

使用C ++ 11甚至线程都不是问题,因为初始化保证可以安全地工作(如果两个线程同时调用该函数,则会等待另一个完成单例的初始化)。