对于我的项目,我正在从头开始编写一些STL容器(我有理由)。由于我如此密切地模仿STL的功能和接口,我正在尽力遵守策略“如果它与标准构造具有相同的名称,它将尽可能符合标准。”
因此,当然我的容器将分配器作为模板参数,这非常好,因为它允许一些自定义分配方案。关于我的问题。
std::allocator
接口将内存分配与对象构造分开。同样,它将解除分配与破坏分开。这是有道理的,因为从中获取内存与在c ++中正确构造对象或多或少无关。
所以有两个构造/释放函数对于默认实现看起来像这样(直接从书中解除):
void construct(pointer p, const T& val) { new(p) T(val); }
void destroy(pointer p) { p->~T(); }
正如你所看到的,构造只是调用placement new而destroy只是调用析构函数。
有没有理由使用这些而不仅仅使用placement new和析构函数语法?一个“正确的”分配器可以用另一种方式实现这些吗?或者我保证所有符合标准的分配器实现都会以这种方式实现构造/销毁方法吗?
更重要的是,可以说我可以随时使用std::uninitialized_copy
和std::uninitialized_fill
来构建容器的元素吗?
感谢。
答案 0 :(得分:11)
分配器可以在构造/销毁之前和之后添加日志记录语句,或者它所关心的任何其他副作用。
当然,实际的构造必须通过调用placement new和析构函数来实现,但是在规则手册中没有说没有别的必须在构造/销毁函数中发生
答案 1 :(得分:3)
这只是隐藏方法中分配的细节。即,我们正在提供建设和销毁的API,将来我们可以改变实施。现在我们使用placement new来分配内存,将来如果我们想要更改分配,我们只需更改这两种方法。