| 作者 | Thorsten Ottosen |
|---|---|
| 联系方式 | nesotto@cs.aau.dk 或 tottosen@dezide.com |
| 组织 | 奥尔堡大学计算机科学系 和 Dezide Aps |
| 日期 | 2007 年 10 月 27 日 |
| 版权 | Thorsten Ottosen 2004-2007。使用、修改和分发受 Boost 软件许可证 1.0 版(参见 LICENSE_1_0.txt)的约束。 |
Boost.Pointer Container 提供了以异常安全且开销极小的方式容纳堆分配对象的容器。该库的目的是通过建立一套处理 OO 特定问题的标准类、方法和设计,使 C++ 中的 OO 编程更加容易。
每当程序员想要拥有一个指向堆分配对象的指针容器时,通常只有一种异常安全的方式:创建一个智能指针容器,如 boost::shared_ptr。如果以下情况,此方法不是最优的:
因此,该库提供了类似标准的容器,用于存储堆分配或克隆的对象(或在映射的情况下,映射对象必须是堆分配或克隆的对象)。对于每个标准容器,都有一个指针容器的等价物,它以异常安全的方式拥有对象。在这方面,该库旨在解决所谓的多态类问题。
指针容器的优点是
缺点是
如果您需要共享语义,则此库不是您需要的。
如果您从这些 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()
}
除了上述更改外,该库现在还引入了
std::auto_ptr<T>重载
std::auto_ptr<T> p( new T ); container.push_back( p );
派生到基类的转换在您可以使用:
boost::ptr_vector<Base> vec; boost::ptr_list<Derived> list; ... vec.transfer( vec.begin(), list ); // now ok
还要注意,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 );
ptr_vector<T>有一些新的辅助函数,可以更好地与 C 数组集成
void transfer( iterator before, T** from, size_type size, bool delete_from = true ); T** c_array();
最后,您现在还可以通过调用auto_type"复制"和"赋值"一个move():
boost::ptr_vector<T>::auto_type move_ptr = ...; return boost::ptr_container::move( move_ptr );
ptr。
<boost/ptr_container/ptr_circular_buffer.hpp>这些类还没有文档,但它们几乎与, boost::ptr_set<T>andboost::ptr_map<Key,T>boost::ptr_array<T,N>
Boost.Circular Buffer
此外,还添加了插入迭代器。1.67.0从 Boost v. 开始std::unique_ptr,Boost.Pointer Container 将使用 Boost.Config 来有条件地提供`std::auto_ptr`接口,以支持或替代使用
compatible-smart-ptr<T>
的接口。详情请参阅兼容智能指针页面,该页面还解释了本文档中用于指示此类条件接口的约定。
对于 C++98/03 用户,此更改没有可观察到的影响。
对于 C++11/14 用户,对使用先前版本的 Boost.Pointer Container 的现有代码没有影响,但现在所有接受`std::auto_ptr`参数的函数重载都附带一个接受std::unique_ptr的重载。在返回类型的情况下,`std::auto_ptr`仍然始终使用。但请注意,直到 C++17,可以隐式构造构造从std::auto_ptr<T>。因此,用户可以自由地通过替换所有显式提及`std::auto_ptr`带有std::unique_ptr来现代化其代码。此更改略低于搜索和替换转换,因为某些代码可能依赖于`std::auto_ptr`是可复制的。但这种情况将导致编译时错误,应易于修复。
虽然`std::auto_ptr`as of ISO C++17 formally removed, certain compiler or standard library vendors have chosen to leave it in for backwards compatibility. For compilers and standard libraries where this is not the case, C++17 compilation of code using Boost.Pointer Container is not possible with Boost v.1.66.*or earlier. This situation is fixed as of Boost v.1.67.0.
有迹象表明void*实现比T*基于的实现。此外,T*基于的实现使用类型安全的方式与算法配合使用要容易得多。因此,我预计将转向T*基于的实现。
此外,可能允许克隆分配器具有状态。此设计需要一些思考,因此如果您有好的想法和用例,请随时与我联系。
此外,Boost.Interprocess 的支持也在待办事项列表中。
有一些关于boost::ptr_multi_index_container<T,...>的请求。我研究了它的难度,发现它确实很难,但并非不可能。但我没有资源来实现这个庞然大物多年,所以如果有人真的需要这个容器,我建议他们私下与我讨论如何实现。
以下人员提供了极大的帮助
| [1] | Matt Austern:"The Standard Librarian: Containers of Pointers",C/C++ Users Journal Experts Forum。 |
| [2] | Bjarne Stroustrup,“The C++ Programming Language”,附录 E:“Standard-Library Exception Safety” |
| [3] | Herb Sutter,“Exceptional C++”。 |
| [4] | Herb Sutter,“More Exceptional C++”。 |
| [5] | Kevlin Henney:“From Mechanism to Method: The Safe Stacking of Cats”,C++ Experts Forum,2002 年 2 月。 |
| [6] | 我看到的一些较早的指针容器的尝试是相当有趣的 NTL 和 pointainer。截至本文撰写之时,这两个库都不是异常安全的,并且可能导致内存泄漏。 |
| [7] | 国际标准,编程语言---C++,ISO/IEC 14882,1998。特别是参见第 23 节。 |
| [8] | C++ 标准库已关闭问题列表(第 27 版),项目 218,算法不使用二元谓词对象进行默认比较。 |
| [9] | C++ 标准库活动问题列表(第 27 版),项目 226,用户提供的 namespace std 函数模板的特化或重载。 |
| [10] | Harald Nowak,“A remove_if for vector”,C/C++ Users Journal,2001 年 7 月。 |
| [11] | (1,2) Boost 智能指针 计时 |
| [12] | (1,2) NTL:Array vs std::vector and boost::shared_ptr |
| [13] | Kevlin Henney,Null Object,2002。 |
| 版权 | Thorsten Ottosen 2004-2006。 |
|---|