是否有任何方法从类的重载新运算符初始化类的成员字段的值?我可以在运算符new中设置对象的值,但是在它返回我的预初始化对象之后,类构造函数会覆盖所有未初始化的值(至少在调试编译中)。
我要做的是:分配器,它使用对象的桶向量,其中新创建的对象一个一个地填充桶。每个桶存储填充槽的数量和下一个填充槽的索引,分配器增加该数量,删除减少。当总量达到零时,它将桶移动到桶向量的末尾,因此当分配程序填充当前填充桶时,它要么重用空桶(并将其移动到向量的开始),要么创建并添加一个新的桶。但是,为了让删除者知道要减少哪个桶的数量,它需要一个指向放置此对象的桶的指针(否则,我需要在向量中搜索每个桶,以找到被删除的对象,或者将对象指针映射到桶中)。
因此,我试图从分配器将当前的桶指针写入对象本身。但是构造函数用nullptr覆盖它。
发布于 2022-02-07 21:56:34
如果您的对象有一个桶ID/指针作为成员,则必须在对象的构造函数中初始化它。这里没有如果,但是,或者可能。这样做的一种方法是:
auto [bucket, slotAddress] = findFreeSlot(sizeof(MyObject));
MyObject* newObject = new (slotAddress) MyObject{bucket}; // placement new
// optionally
someSmartPtr<MyObject, CustomDeleter> ptr{newObject, customDeleter};这里不需要定制重载的operator new。
如果您绝对肯定必须在重载的operator new中初始化桶,请不要使桶成为对象的成员。相反,将其分配并初始化为一段辅助信息,就像标准的operator new存储有关内存块的记账信息一样。例如(未经测试的,可能有UB,但如果您正在编写自定义分配器,您可能知道如何正确地执行此操作):
struct block {
std::aligned_storage_t<sizeof(Bucket)> buck;
};
void* operator new (size_t size) {
auto [bucket, slotAddress] = findFreeSlot(sizeof(block) + size);
block* blk = new(slotAddress) block;
Bucket* bck = new(&blk->buck) Bucket(bucket);
return blk+1;
}现在您可以从MyObject的地址转到桶ID/指针:
Bucket bucketOfMyObject (MyObject* m) {
block* b = reinterpret_cast<block*>(m) - 1;
return *reinterpret_cast<Bucket*>(b->buck);
}https://stackoverflow.com/questions/71024046
复制相似问题