【问题标题】:When is it useful to have custom construct/destroy methods in allocators?在分配器中使用自定义构造/销毁方法什么时候有用?
【发布时间】:2025-11-27 08:20:04
【问题描述】:

自定义分配器,特别是自定义allocate/deallocate 方法的能力非常有用 - 允许控制在某些性能关键区域中使用的低级内存分配策略。 Pooled allocators 代表基于节点的容器,fixed-size allocators 是我想到的几个例子。

但是什么时候定义自定义construct/destroy 方法有用呢?

据我了解,标准要求这些方法与放置new 和显式销毁具有相同的效果,即:

//construct should give the same effect as:
    construct (_Type *_ptr, _Type const&_val)
    {
        new(_ptr) _Type(_val);
    }
//destroy should give the same effect as:
    destroy (_Type *_ptr)
    {
        _ptr->~_Type();
    }

有没有办法以另一种方式实现这些方法 - 不使用放置 new 和显式销毁?如果不是,为什么它们是分配器对象的一部分?大家直接用placementnew和显式销毁不是更简单吗?

【问题讨论】:

  • construct 函数可能除了放置新位置之外还可以做其他事情。这是一个自定义点,如果你需要它很好。
  • @BoPersson:有没有一个实际的例子来说明“其他东西”是什么?我还没有想出任何不能更好地放在实际对象类型本身的ctor/dtor 中的东西......另外,如果construct/destroy 确实做了与普通对象创建/销毁不同的事情,那么本地的行为在堆栈上创建的对象与通过分配器创建的对象不同。这合理吗?
  • 这是在分配器中具有此功能的原因之一。当容器存储在共享内存中时,也许需要一些特殊的?它允许包含的对象不同于堆栈对象。
  • 更多答案在这里:*.com/q/652715/395718

标签: c++


【解决方案1】:

对于在模板参数周围替换包装器类型并对其进行操作的分配器,constructdestroy 应该调用包装器构造函数和析构函数,而不是分配的类型。

在 C++11 中,construct 将任意数量的参数转发给构造函数。自定义分配器可以在列表的开头或结尾插入参数,或者以其他方式拦截和修改参数。不过,这仅在用户使用就地构造时才有效。

顺便说一句,你不应该使用_Type 作为标识符;带有前导下划线后跟大写的标识符被保留用于实现。

【讨论】:

    最近更新 更多