我的代码如下。但是,在运行main()
之前,诸如static std::string globalvar;
之类的简单操作会调用new。在MyPool mypool
初始化之前。
MyPool mypool;
void* operator new(size_t s) { return mypool.donew(s); }
无论如何我可以强制mypool先被初始化吗?如果无法初始化其值,我不知道如果重载new是如何工作的,所以我确信有一个解决方案。
我正在使用视觉工作室2010和gcc(跨平台)
答案 0 :(得分:2)
使mypool
成为operator new
函数的静态变量:
void* operator new(size_t s) {
static MyPool mypool;
return mypool.donew(s);
}
首次调用函数(即运算符new
)时,它将被初始化。
编辑:正如评论者指出的那样,在static
函数中将变量声明为operator new
会限制其范围,并使其在operator delete
中无法访问。要解决这个问题,您应该为池对象创建一个访问器函数:
MyPool& GetMyPool() {
static MyPool mypool;
return mypool;
}
并在operator new
和operator delete
中调用它:
void* operator new(size_t s) {
return GetMyPool().donew(s);
}
// similarly for delete
和以前一样,将它声明为静态局部变量可以保证在第一次调用GetMyPool
函数时进行初始化。此外,它将是两个运算符中相同的池对象,可能是您想要的。
答案 1 :(得分:2)
正确?最好不要。试试Boost.Pool,然后使用他们的分配机制。或者,如果您坚持使用池,请创建一个新的分配功能。我已经看到operator new
做了可怕的事情,我为此感到难过。 :(
恕我直言,唯一应该重载new
的是实现内存管理器以观察allocs / deallocs。否则,只需编写自己的函数并使用它们。或者对于大多数容器,您可以给它们分配器。
答案 2 :(得分:2)
全局初始化分三步进行,零初始化,静态
初始化和动态初始化。以该顺序。如果你的
operator new
使用非局部变量,这些变量必须依赖
只有零或静态初始化;正如你所说,你无法保证
在任何特定变量之前不会调用operator new
动态初始化将会发生。
如果您需要具有动态初始化的对象(通常是这种情况),那么 有两种处理方式:
声明指向对象的指针,而不是对象本身,和
在operator new
中,检查指针是否为空,并初始化它
那里,或
调用一个函数,该函数返回对本地实例的引用。
这些解决方案都不是线程安全的,但这可能不是
问题。一旦第一次调用返回,它们 线程安全,所以如果
在线程开始之前有new
的任何调用,你没关系。
(但是要记住这一点。如果不确定,你可以永远
在第一个线程之前手动分配和删除对象
开始 - 也许是在静态对象的初始化中。)