首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从重载的新运算符初始化类成员

从重载的新运算符初始化类成员
EN

Stack Overflow用户
提问于 2022-02-07 19:06:36
回答 1查看 76关注 0票数 -1

是否有任何方法从类的重载新运算符初始化类的成员字段的值?我可以在运算符new中设置对象的值,但是在它返回我的预初始化对象之后,类构造函数会覆盖所有未初始化的值(至少在调试编译中)。

我要做的是:分配器,它使用对象的桶向量,其中新创建的对象一个一个地填充桶。每个桶存储填充槽的数量和下一个填充槽的索引,分配器增加该数量,删除减少。当总量达到零时,它将桶移动到桶向量的末尾,因此当分配程序填充当前填充桶时,它要么重用空桶(并将其移动到向量的开始),要么创建并添加一个新的桶。但是,为了让删除者知道要减少哪个桶的数量,它需要一个指向放置此对象的桶的指针(否则,我需要在向量中搜索每个桶,以找到被删除的对象,或者将对象指针映射到桶中)。

因此,我试图从分配器将当前的桶指针写入对象本身。但是构造函数用nullptr覆盖它。

EN

回答 1

Stack Overflow用户

发布于 2022-02-07 21:56:34

如果您的对象有一个桶ID/指针作为成员,则必须在对象的构造函数中初始化它。这里没有如果,但是,或者可能。这样做的一种方法是:

代码语言:javascript
复制
 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,但如果您正在编写自定义分配器,您可能知道如何正确地执行此操作):

代码语言:javascript
复制
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/指针:

代码语言:javascript
复制
Bucket bucketOfMyObject (MyObject* m) {
   block* b = reinterpret_cast<block*>(m) - 1;
   return *reinterpret_cast<Bucket*>(b->buck);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71024046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档