使用自定义分配器调用对象构造函数/析构函数
Callling object constructor/destructor with a custom allocator
我一直在研究自定义分配器,我经常看到它们使用某种函数来分配内存。为了测试目的和进一步教育我自己,我试图做一个"简单"的例子。但是,关于如何做,我理解一件基本的事情。malloc
与 new
的主要区别之一是,使用 new 调用构造函数。如果我想编写自己的分配器,本质上是替换new
,如何在使用malloc
时调用构造函数?
上我可以重载类new
和delete
,所以我想问题的很大一部分是,new
如何在分配期间调用对象构造函数?同样,我对delete
如何调用析构函数感兴趣。
我创建了一个示例测试代码,我希望在分配期间调用 SomeClass
构造函数,但我看不出如何。
#include <malloc.h>
void* SomeAllocationFunction(size_t size) {
return malloc(size);
}
class SomeClass
{
public:
SomeClass() {
int con = 1000;
}
~SomeClass() {
int des = 80;
}
};
int main(void){
SomeClass* t = (SomeClass*)SomeAllocationFunction(sizeof(SomeClass));
return 0;
}
(请注意,我知道我可以使用new
。但是,出于学习目的,我正在尝试创建一个自定义分配器,它不只是调用new
或placement new
)。
本质上,当您使用新表达式时: T *t = new T;
,它大致相当于:
void *temp = operator new(sizeof(T));
T *t = new(temp) T;
因此,首先它使用分配函数分配一些原始内存,然后在该内存中构造一个对象。同样,当您使用删除表达式时,例如: delete t;
,它大致相当于:
t->~T();
operator delete(t);
因此,如果您重载特定类的new
和delete
:
class T {
int data;
public:
// I've made these static explicitly, but they'll be static even if you don't.
static void *operator new(size_t size) {
return malloc(size);
}
static void operator delete(void *block) {
free(block);
}
};
然后当你使用一个新表达式时,它会调用类的operator new
来分配内存,这将调用malloc
,所以T *t = new T();
最终将通过malloc
分配内存(同样,当你delete
它时,它将使用 operator delete
,这将调用free
)。
至少在通常使用该术语时,分配器非常相似,只是它由容器而不是其他代码使用。它还将分配函数和删除函数封装到一个类中,因此当您将一个对象传递给容器时,您只需要传递一个对象,并且分配和删除函数不匹配的可能性很小。
暂时忽略有关用于事物的名称的详细信息,标准库中的 Allocator 类大多做同样的事情,因此只需对上面 T
类中的函数进行一些重命名,您大约完成了编写标准分配器的一半。为了进行分配和删除,它有一个功能来rebind
一些内存(将内存块更改为另一种类型),就地创建一个对象(基本上只是围绕放置新位置的包装器)和销毁一个对象(再次,围绕析构函数调用的琐碎包装器)。当然,它使用operator new
和operator delete
,而不是像我上面使用的那样malloc
和free
。
使用放置 new,您可以将已分配的内存位置传递给新运算符。然后 new 将在给定位置构造对象,而无需对自身进行分配。
编辑:
这是它的实现方式:
int main(void){
// get memory
void * mem_t = SomeAllocationFunction(sizeof(SomeClass));
// construct instance
SomeClass* t = new(mem_t) SomeClass;
// more code
// clean up instance
t->~SomeClass();
return 0;
}
要调用构造函数,请使用放置 new(注意你不能覆盖放置 new)。对于删除和所有陷阱,常见问题解答很好地解释了它。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- new[] / delete[] 并在C++中抛出构造函数/析构函数
- 创建/向容器添加对象时如何使用构造函数/析构函数
- LNK2019构造函数/析构函数使用 C++ Dll
- 有人可以解释一下这里发生了什么(类和构造函数/析构函数)吗?
- 带智能ptr的Pimpl-为什么需要构造函数/析构函数
- 需要构造函数/析构函数/类型转换错误
- Boost共享指针构造函数/析构函数
- 通过值或引用调用时未调用构造函数/析构函数.不管怎样
- C++构造函数析构函数中的奇怪行为
- 构造函数/析构函数链接错误
- 在模板化函数中调用具有特征的显式构造函数/析构函数
- c++构造函数/析构函数
- 为什么赋值的成本不能保证小于构造函数-析构函数对
- 重写默认构造函数/析构函数而不实现它们
- 使用自定义分配器调用对象构造函数/析构函数
- 涉及类和结构的构造函数/析构函数
- 在抽象构造函数/析构函数中调用纯虚拟函数安全吗
- 如果在没有限定的情况下从构造函数/析构函数调用虚拟函数,则是否会发生虚拟调度
- C++基于堆栈的构造函数/析构函数无法按预期工作