Boost Pointer Container Library 指針容器庫

Author: Thorsten Ottosen
Contact: nesotto@cs.aau.dk or tottosen@dezide.com
Organizations: Department of Computer Science, Aalborg University, and Dezide Aps
Date: 27th of October 2007
Copyright: Thorsten Ottosen 2004-2007. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt).

Overview 總覽

Boost.Pointer Container provides containers for holding heap-allocated objects in an exception-safe manner and with minimal overhead. The aim of the library is in particular to make OO programming easier in C++ by establishing a standard set of classes, methods and designs for dealing with OO specific problems
Boost.Pointer Container 以異常安全的風格和最小的開銷提供了保存堆分配對象的容器。本庫的目標是通過為處理OO特定問題建立一套標準的類、方法和設計,來使得用C++進行OO編 程更為容易。

Motivation 動機

Whenever a programmer wants to have a container of pointers to heap-allocated objects, there is usually only one exception-safe way: to make a container of smart pointers like boost::shared_ptr This approach is suboptimal if
當一個程序員想要一個堆分配對像指針的容器時,通常只有一個異常安全的方法:建造一個智能指針如 boost::shared_ptr 的容器。這個方法並不是最理想的,如果:

  1. the stored objects are not shared, but owned exclusively, or
    被保存的對象並不是共享的,而是專有的,或者
  1. the overhead implied by smart pointers is inappropriate
    智能指針所帶來的開銷是不適當的

This library therefore provides standard-like containers that are for storing heap-allocated or cloned objects (or in case of a map, the mapped object must be a heap-allocated or cloned object). For each of the standard containers there is a pointer container equivalent that takes ownership of the objects in an exception safe manner. In this respect the library is intended to solve the so-called polymorphic class problem.
因此本庫提供了與標準相似的容器,用於保存堆分配的或克隆的對像(或者 在 map 中,被映射的對象必須一個堆分配的或克隆的對象)。對於每一種標準容器,都有一個等價的指針容器,以一種異常安全的方式來接受對象的擁有權。在這方面,本 庫的目的是解決被稱為 多態類的問題

The advantages of pointer containers are
指針容器的優點是:

  1. Exception-safe pointer storage and manipulation.
    異常安全的指針存儲和操作。
  1. Notational convenience compared to the use of containers of pointers.
    比使用指針的容器更方便的寫法。
  1. Can be used for types that are neither Assignable nor Copy Constructible.
    可用於既不可賦值也不可複製構造的類型。
  1. No memory-overhead as containers of smart pointers can have (see [11] and [12]).
    無內存開銷,而智能指針容器可能會有(參見 [11][12])。
  1. Usually faster than using containers of smart pointers (see [11] and [12]).
    通常比智知指針容器更快(參見 [11][12])。
  1. The interface is slightly changed towards the domain of pointers instead of relying on the normal value-based interface. For example, now it is possible for pop_back() to return the removed element.
    接口有些修改,接近於指針接口而不是依賴於普通的值接口。例如,pop_back() 有可能返回被刪除的元素。
  1. Propagates constness such that one cannot modify the objects via a const_iterator.
    傳播常量性,你不能通過 const_iterator 修 改對象。
  1. Built-in support for deep-copy semantics via the the Cloneable concept
    內建的對深複製語義的支持,通過 可克隆概念 實現。

The disadvantages are
缺點是:

  1. Less flexible than containers of smart pointers like boost::shared_ptr
    與智能指針容器如 boost::shared_ptr 相比,靈活性較少。

When you do need shared semantics, this library is not what you need.
如果你需要分享的語義,那麼本庫不是你所需要的。

Upgrading from Boost v. 1.33.* 從 Boost v. 1.33.* 升級

If you upgrade from one of these versions of Boost, then there has been one major interface change: map iterators now mimic iterators from std::map. Previously you may have written
如果你從 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()
}

and this now needs to be converted into
而現在要變成這樣:

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()
}

Apart from the above change, the library now also introduces
除了以上變化,本庫現在還引入了:

Also note that Boost.Assign introduces better support for pointer containers.
還是留意 Boost.Assign 引入了對指針容器更好的支持。

Upgrading from Boost v. 1.34.* 從 Boost v. 1.34.* 升級

Serialization have now been made optional thanks to Sebastian Ramacher. You simply include <boost/ptr_container/serialize.hpp> or perhaps just one of the more specialized headers.
序列化現在是可選的了,感謝 Sebastian Ramacher。你只要包含 <boost/ptr_container/serialize.hpp> 或者只需其中某一個特定頭文件即可。

All containers are now copy-constructible and assignable. So you can e.g. now do:
所有容器現在都是可複製構造和可賦值的。所以現在你可以這樣做:

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

As the example shows, derived-to-base class conversions are also allowed.
如上例所示,派生類至基類的轉換也是允許的。

A few general functions have been added:
增加了少量常用函數:

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

These allow direct access to the wrapped container which is somtimes needed when you want to provide extra functionality.
這些函數允許直接訪問被包裝的容器,當你想提供更多的功能時就會需要這樣的容器。

A few new functions have been added to sequences:
對於序列容器,增加了少量函數:

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

ptr_vector<T> has a few new helper functions to integrate better with C-arrays:
ptr_vector<T> 有新的輔助函數,以更好地與C數組集成:

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

Finally you can now also "copy" and "assign" an auto_type ptr by calling move():
最後,現在你也可以通過調用 move() "複製"和"賦值"一個 auto_type 指針:

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

Upgrading from Boost v. 1.35.* 從 Boost v. 1.35.* 升級

The library has been fairly stable, but a few new containers have been supported:
本庫已相當穩定,但是有少量新的容器獲得支持:

  • boost::ptr_unordered_set<T> in <boost/ptr_container/ptr_unordered_set.hpp>
  • boost::ptr_unordered_map<Key,T> in <boost/ptr_container/ptr_unordered_map.hpp>
  • boost::ptr_circular_buffer<T> in <boost/ptr_container/ptr_circular_buffer.hpp>

There are no docs for these classes yet, but they are almost identical to boost::ptr_set<T>, boost::ptr_map<Key,T> and boost::ptr_array<T,N>, respectively. The underlying containers stem from the two boost libraries
目前這些類還沒有文檔,但是它們分別與 boost::ptr_set<T>, boost::ptr_map<Key,T>boost::ptr_array<T,N> 幾乎完全一樣。底層的容器來自於以下兩個 boost 庫:

Furthermore, insert iterators have been added.
此外,還增加了 插入迭代器

Future Developments 未來的發展

There are indications that the void* implementation has a slight performance overhead compared to a T* based implementation. Furthermore, a T* based implementation is so much easier to use type-safely with algorithms. Therefore I anticipate to move to a T* based implementation.
有跡象表明,void* 的實現與基於 T* 的實現相比性能開銷稍多一點。此外,基於 T* 的實現更易於異常安全地使用算法。因此我準備轉移到一個基於 T* 的實現。

Furthermore, the clone allocator might be allowed to have state. This design requires some thought, so if you have good ideas and use-cases' for this, please don't hesitate to contact me.
此外,克隆分配器可能允許具有狀態。這種設計需要一些思路,所以如果你有好的想法以及相關用例,請不要猶豫,立即聯繫我。

Also, support for Boost.Interprocess is on the todo list.
還有,對 Boost.Interprocess 的支持也在待辦事項列表中。

There has been a few request for boost::ptr_multi_index_container<T,...>. I investigated how difficult it would be, and it did turn out to be difficult, albeit not impossible. But I don't have the resources to implement this beast for years to come, so if someone really needs this container, I suggest that they talk with me in private about how it can be done.
有些請求是關於 boost::ptr_multi_index_container<T,...> 的。我研究了它的實現有何困難,發現的確很難,雖然不是不可能。未來幾年我都沒有資源來實現這個東西,所以如果有人真的需要這個容器,我建議他們私下告訴我它可以怎樣實現。

Acknowledgements 鳴謝

The following people have been very helpful:
以下人員提供了非常大的幫助:

References 參考文檔

[1] Matt Austern: "The Standard Librarian: Containers of Pointers" , C/C++ Users Journal Experts Forum.
[2] Bjarne Stroustrup, "The C++ Programming Language", Appendix 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, February 2002.
[6] Some of the few earlier attempts of pointer containers I have seen are the rather interesting NTL and the pointainer. As of this writing both libraries are not exceptions-safe and can leak.
[7] INTERNATIONAL STANDARD, Programming languages --- C++, ISO/IEC 14882, 1998. See section 23 in particular.
[8] C++ Standard Library Closed Issues List (Revision 27), Item 218, Algorithms do not use binary predicate objects for default comparisons.
[9] C++ Standard Library Active Issues List (Revision 27), Item 226, User supplied specializations or overloads of namespace std function templates.
[10] Harald Nowak, "A remove_if for vector", C/C++ Users Journal, July 2001.
[11] (1, 2) Boost smart pointer timings
[12] (1, 2) NTL: Array vs std::vector and boost::shared_ptr
[13] Kevlin Henney, Null Object, 2002.

Copyright: Thorsten Ottosen 2004-2006.