Boost C++ 库

...世界上最受推崇和专业设计的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

Boost 指针容器库

作者 Thorsten Ottosen
联系方式 nesotto@cs.aau.dktottosen@dezide.com
组织奥尔堡大学计算机科学系, 以及 Dezide Aps
日期 2007年10月27日
版权 Thorsten Ottosen 2004-2007。使用、修改和分发受 Boost 软件许可,版本 1.0 约束(参见 LICENSE_1_0.txt)。

概述

Boost.Pointer Container 提供了用于以异常安全的方式和最小的开销保存堆分配对象的容器。该库的目标特别是通过建立一套标准的类、方法和设计来简化 C++ 中的 OO 编程,以解决 OO 特有的问题

动机

每当程序员想要拥有一个指向堆分配对象的指针容器时,通常只有一种异常安全的方式:创建一个智能指针容器,例如 boost::shared_ptr。如果出现以下情况,这种方法不是最佳的:

  1. 存储的对象不是共享的,而是独占拥有的,或者
  1. 智能指针带来的开销是不合适的

因此,该库提供了类似标准的容器,用于存储堆分配或克隆的对象(或者在 map 的情况下,映射的对象必须是堆分配或克隆的对象)。对于每个标准容器,都有一个指针容器等效物,它以异常安全的方式获取对象的所有权。在这方面,该库旨在解决所谓的多态类问题

指针容器的优点是

  1. 异常安全的指针存储和操作。
  1. 与使用指针容器相比,符号表示法更方便。
  1. 可用于既不可赋值也不可复制构造的类型。
  1. 没有智能指针容器可能具有的内存开销(参见 [11][12])。
  1. 通常比使用智能指针容器更快(参见 [11][12])。
  1. 接口略微向指针域更改,而不是依赖于正常的基于值的接口。例如,现在可以进行pop_back()以返回删除的元素。
  1. 传播常量性,使得无法通过const_iterator.
  1. 修改对象

通过 Clonable 概念内置对深拷贝语义的支持

  1. 缺点是

不如智能指针容器(如 boost::shared_ptr)灵活

当您确实需要共享语义时,此库不是您需要的。1.33.*

从 Boost v. 升级如果您从这些 Boost 版本之一升级,那么已经发生了一个主要的接口更改:map 迭代器现在模仿来自std::map

for( boost::ptr_map<std::string,T>::iterator i = m.begin(), e = m.end();
     i != e; ++i )
{
  std::cout << "key:" << i.key();
  std::cout << "value:" << *i;
  i->foo(); // call T::foo()
}

的迭代器。以前您可能写过

for( boost::ptr_map<std::string,T>::iterator i = m.begin(), e = m.end();
     i != e; ++i )
{
  std::cout << "key:" << i->first;
  std::cout << "value:" << *i->second;
  i->second->foo(); // call T::foo()
}

而现在需要将其转换为

transfer()

当您确实需要共享语义时,此库不是您需要的。1.34.*

中派生类到基类的转换另请注意,Boost.Assign 引入了对指针容器的更好支持。由于 Sebastian Ramacher 的贡献,序列化现在已成为可选的。您只需包含

<boost/ptr_container/serialize.hpp>

boost::ptr_vector<Derived> derived = ...;
boost::ptr_vector<Base>    base( derived );
base = derived;

或者可能只是更专业化的头文件之一。

所有容器现在都是可复制构造和可赋值的。因此,例如,您现在可以执行

VoidPtrContainer&       base();
const VoidPtrContainer& base() const;

正如示例所示,也允许派生类到基类的转换。

添加了一些通用函数

void resize( size_type size );
void resize( size_type size, T* to_clone );

这些函数允许直接访问包装的容器,当您想提供额外的功能时,有时需要这样做。为序列添加了一些新函数

void transfer( iterator before, T** from, size_type size, bool delete_from = true );
T**  c_array();

ptr_vector<T>有一些新的辅助函数,可以更好地与 C 数组集成最后,您现在也可以通过调用move():

boost::ptr_vector<T>::auto_type move_ptr = ...;
return boost::ptr_container::move( move_ptr );

当您确实需要共享语义时,此库不是您需要的。1.35.*

“复制”和“赋值”一个

<boost/ptr_container/ptr_unordered_map.hpp>boost::ptr_circular_buffer<T>, <boost/ptr_container/ptr_circular_buffer.hpp>这些类还没有文档,但它们几乎与boost::ptr_set<T>boost::ptr_map<Key,T>

分别相同。底层容器源自两个 boost 库

当您确实需要共享语义时,此库不是您需要的。1.66.*

Boost.Unordered1.67.0Boost.Circular Buffer此外,还添加了 插入迭代器从 Boost v. 开始, Boost.Pointer Container 将使用 Boost.Config 有条件地提供std::unique_ptr

compatible-smart-ptr<T>

基于的接口,除了或代替使用

std::auto_ptr

的接口。详细信息请参见 兼容智能指针 页面,该页面还解释了本文档中使用, Boost.Pointer Container 将使用 Boost.Config 有条件地提供来指示此类条件接口的约定。此外,还添加了 插入迭代器对于 C++98/03 用户,此更改没有可观察到的效果。, Boost.Pointer Container 将使用 Boost.Config 有条件地提供对于 C++11/14 用户,对使用先前版本的 Boost.Pointer Container 的现有代码没有影响,但现在所有采用参数的函数重载都伴随着采用的重载。在返回类型的情况下,除了上述更改之外,该库现在还引入了仍然始终使用。但请注意,在 C++17 之前,可以从, Boost.Pointer Container 将使用 Boost.Config 有条件地提供隐式构造此外,还添加了 插入迭代器std::unique_ptr<T>, Boost.Pointer Container 将使用 Boost.Config 有条件地提供。因此,用户可以自由地通过替换任何显式提及的

来现代化他们的代码, Boost.Pointer Container 将使用 Boost.Config 有条件地提供。此更改仅差一步即可进行查找和替换转换,因为某些代码可能依赖于1.66.*是可复制的。但这种情况将导致编译时错误,这应该很容易修复。1.67.0.

未来发展

虽然在 ISO C++17 中正式删除,但某些编译器或标准库供应商已选择将其保留以实现向后兼容性。对于不是这种情况的编译器和标准库,使用 Boost.Pointer Container 的代码的 C++17 编译在 Boost v. 或更早版本中是不可能的。这种情况在 Boost v. 中得到修复。有迹象表明,void*有迹象表明,实现与有迹象表明,T*

基于的实现相比,具有轻微的性能开销。此外,

基于的实现更容易安全地与算法一起使用。因此,我预计会迁移到

基于的实现。此外,克隆分配器可能被允许具有状态。此设计需要一些思考,因此如果您对此有好的想法和用例,请随时与我联系。此外,对 Boost.Interprocess 的支持也在待办事项列表中。

致谢

有人请求

参考文献

[1]Andreas Hommel 修复了令人讨厌的 Metrowerks 错误
[2]Charles Brockman 对文档提出了许多意见
[3]Sebastian Ramacher 实现了可选的序列化支持
[4]Matt Austern: "标准库专家:指针容器" , C/C++ 用户杂志专家论坛。
[5]Bjarne Stroustrup, "C++ 编程语言", 附录 E: "标准库异常安全性"
[6]Herb Sutter, "Exceptional C++".
[7]Herb Sutter, "More Exceptional C++".
[8]Kevlin Henney: "从机制到方法:猫的安全堆叠" , C++ 专家论坛, 2002 年 2 月。
[9]我所见过的早期指针容器尝试中的一些是相当有趣的 NTLpointainer。在撰写本文时,这两个库都不是异常安全的,可能会泄漏。
[10]国际标准,编程语言 --- C++, ISO/IEC 14882, 1998。 特别参见第 23 节。
[11]C++ 标准库已关闭问题列表(修订版 27),项目 218,算法不使用二元谓词对象进行默认比较
[12]C++ 标准库活动问题列表(修订版 27),项目 226,用户提供的命名空间 std 函数模板的特化或重载
[13]Harald Nowak, "vector 的 remove_if", C/C++ 用户杂志, 2001 年 7 月。

版权(1, 2) Boost 智能指针 计时