看看这篇文章:C++ 中的重载新功能。您可以重载new
运算符 forObjectBase
以便它将分配器作为参数并完成其余工作:
void *ObjectBase::operator new(size_t size, Allocator *allocator) {
void *ptr = allocator->allocate(size);
// Hack to pre-initialize member before constructor is called
ObjectBase *obj = static_cast<ObjectBase *>(ptr);
obj->setAllocator(allocator);
return ptr;
}
通常,操作符应该只返回一个指向已分配内存的指针,但是由于您需要访问新对象来调用您的setAllocator
方法,所以我提供了一个应该(但可能不会)工作的技巧。请注意,实际的ObjectBase
构造函数是在上述函数返回后调用的,因此您应该确保您的构造函数不会重新初始化分配器成员。
然后是类似的重载delete
:
void ObjectBase::operator delete(void *ptr) {
ObjectBase *obj = static_cast<ObjectBase *>(ptr);
obj->getAllocator()->free(ptr);
}
然后,您将通过调用new (allocator) SomeClass(...)
where SomeClass
derived from 来创建对象ObjectBase
。
Edit: One potential problem with this is that you cannot allocate objects on the stack any more, because there is no way to initialize the allocator to NULL
without affecting the how the overloaded new
works.
Update: There is one last (dirty) hack to get it working with both stack and dynamic allocation. You can make new
set a global variable (a class static member would work as well) pointing to the current allocator and the constructor could consume this and reset it to NULL
. At all other times, this global will already be NULL
so an object constructed on the stack will get a NULL
allocator.
Allocator *currentAllocator = NULL;
void *ObjectBase::operator new(size_t size, Allocator *allocator) {
currentAllocator = allocator;
return allocator->allocate(size);
}
ObjectBase::ObjectBase() {
setAllocator(currentAllocator);
currentAllocator = NULL;
}