我正在尝试为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开始创建时,像池一样没有分配内存。
答案 0 :(得分:3)
在类中声明为static
的对象基本上是一个具有滑稽名称的全局对象。全局对象的规则是它们将在main
开始之前创建,并在main
结束后以未指定的顺序销毁。唯一的保证是,如果特定的编译单元(即.cpp文件)有两个全局对象A
,B
和A
出现在B
之前,那么{{1将在A
之前构建。
因此,如果您没有B
的任何全局实例,那么一切都没问题,否则您就会遇到问题。
常见的解决方案是使用静态函数返回对本地静态对象的引用,而不是使用全局对象,即
Foo
这解决了这个问题,因为函数内部的静态对象将在第一次调用函数时构造。在这种情况下,您只需要注意多线程(即,如果存在两个线程同时进入静态函数的风险)。
使用C ++ 11甚至线程都不是问题,因为初始化保证可以安全地工作(如果两个线程同时调用该函数,则会等待另一个完成单例的初始化)。