mirror of
https://github.com/boostorg/ptr_container.git
synced 2026-01-30 20:12:33 +00:00
114 lines
11 KiB
HTML
114 lines
11 KiB
HTML
<?xml version="1.0" encoding="utf-8" ?>
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<meta name="generator" content="Docutils 0.3.7: http://docutils.sourceforge.net/" />
|
|
<title>Boost Pointer Container Library</title>
|
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
|
</head>
|
|
<body>
|
|
<div class="document" id="boost-pointer-container-library">
|
|
<h1 class="title"><img alt="Boost" src="cboost.gif" /> Pointer Container Library</h1>
|
|
<h2 class="subtitle" id="faq">FAQ</h2>
|
|
<div class="contents topic" id="contents">
|
|
<ul class="simple">
|
|
<li><a class="reference" href="#since-a-pointer-container-is-not-copy-constructible-and-assignable-i-cannot-put-them-into-standard-containers-what-do-i-do" id="id4" name="id4">Since a pointer container is not Copy Constructible and Assignable, I cannot put them into standard containers; what do I do?</a></li>
|
|
<li><a class="reference" href="#calling-assign-is-very-costly-and-i-do-not-really-need-to-store-cloned-objects-i-merely-need-to-overwrite-the-existing-ones-what-do-i-do" id="id5" name="id5">Calling <tt class="docutils literal"><span class="pre">assign()</span></tt> is very costly and I do not really need to store cloned objects; I merely need to overwrite the existing ones; what do I do?</a></li>
|
|
<li><a class="reference" href="#which-mutating-algorithms-are-safe-to-use-with-pointers" id="id6" name="id6">Which mutating algorithms are safe to use with pointers?</a></li>
|
|
<li><a class="reference" href="#why-does-ptr-map-t-insert-replace-take-two-arguments-the-key-and-the-pointer-instead-of-one-std-pair-and-why-is-the-key-passed-by-non-const-reference" id="id7" name="id7">Why does <tt class="docutils literal"><span class="pre">ptr_map<T>::insert()/replace()</span></tt> take two arguments (the key and the pointer) instead of one <tt class="docutils literal"><span class="pre">std::pair</span></tt>? And why is the key passed by non-const reference?</a></li>
|
|
<li><a class="reference" href="#when-instantiating-a-pointer-container-with-a-type-t-is-t-then-allowed-to-be-incomplete-at-that-point" id="id8" name="id8">When instantiating a pointer container with a type <tt class="docutils literal"><span class="pre">T</span></tt>, is <tt class="docutils literal"><span class="pre">T</span></tt> then allowed to be incomplete at that point?</a></li>
|
|
<li><a class="reference" href="#why-do-iterator-range-inserts-give-the-strong-exception-safety-guarantee" id="id9" name="id9">Why do iterator-range inserts give the strong exception-safety guarantee?</a></li>
|
|
<li><a class="reference" href="#what-is-the-polymorphic-class-problem" id="id10" name="id10">What is the polymorphic class problem?</a></li>
|
|
<li><a class="reference" href="#are-the-pointer-containers-faster-and-do-they-have-a-better-memory-footprint-than-a-container-of-pointer-pointers" id="id11" name="id11">Are the pointer containers faster and do they have a better memory footprint than a container of pointer pointers?</a></li>
|
|
<li><a class="reference" href="#when-the-stored-pointers-cannot-be-0-how-do-i-allow-this-empty-behavior-anyway" id="id12" name="id12">When the stored pointers cannot be <tt class="docutils literal"><span class="pre">0</span></tt>, how do I allow this "empty" behavior anyway?</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="since-a-pointer-container-is-not-copy-constructible-and-assignable-i-cannot-put-them-into-standard-containers-what-do-i-do">
|
|
<h1><a class="toc-backref" href="#id4" name="since-a-pointer-container-is-not-copy-constructible-and-assignable-i-cannot-put-them-into-standard-containers-what-do-i-do">Since a pointer container is not Copy Constructible and Assignable, I cannot put them into standard containers; what do I do?</a></h1>
|
|
<p>Since they are <a class="reference" href="reference.html#the-clonable-concept">Clonable</a>, you simply put them in a pointer container.</p>
|
|
</div>
|
|
<div class="section" id="calling-assign-is-very-costly-and-i-do-not-really-need-to-store-cloned-objects-i-merely-need-to-overwrite-the-existing-ones-what-do-i-do">
|
|
<h1><a class="toc-backref" href="#id5" name="calling-assign-is-very-costly-and-i-do-not-really-need-to-store-cloned-objects-i-merely-need-to-overwrite-the-existing-ones-what-do-i-do">Calling <tt class="docutils literal"><span class="pre">assign()</span></tt> is very costly and I do not really need to store cloned objects; I merely need to overwrite the existing ones; what do I do?</a></h1>
|
|
<p>Call <tt class="docutils literal"><span class="pre">std::copy(</span> <span class="pre">first,</span> <span class="pre">last,</span> <span class="pre">c.begin()</span> <span class="pre">);</span></tt>.</p>
|
|
</div>
|
|
<div class="section" id="which-mutating-algorithms-are-safe-to-use-with-pointers">
|
|
<h1><a class="toc-backref" href="#id6" name="which-mutating-algorithms-are-safe-to-use-with-pointers">Which mutating algorithms are safe to use with pointers?</a></h1>
|
|
<p>Any mutating algorithm that moves elements around by swapping them. An
|
|
important example is <tt class="docutils literal"><span class="pre">std::sort()</span></tt>; examples of unsafe algorithms are
|
|
<tt class="docutils literal"><span class="pre">std::unique()</span></tt> and <tt class="docutils literal"><span class="pre">std::remove()</span></tt>.</p>
|
|
<!-- That is why these algorithms are
|
|
provided as member functions. -->
|
|
</div>
|
|
<div class="section" id="why-does-ptr-map-t-insert-replace-take-two-arguments-the-key-and-the-pointer-instead-of-one-std-pair-and-why-is-the-key-passed-by-non-const-reference">
|
|
<h1><a class="toc-backref" href="#id7" name="why-does-ptr-map-t-insert-replace-take-two-arguments-the-key-and-the-pointer-instead-of-one-std-pair-and-why-is-the-key-passed-by-non-const-reference">Why does <tt class="docutils literal"><span class="pre">ptr_map<T>::insert()/replace()</span></tt> take two arguments (the key and the pointer) instead of one <tt class="docutils literal"><span class="pre">std::pair</span></tt>? And why is the key passed by non-const reference?</a></h1>
|
|
<p>This is the only way the function can be implemented in an exception-safe
|
|
manner; since the copy-constructor of the key might throw, and since
|
|
function arguments are not guaranteed to be evaluated from left to right,
|
|
we need to ensure that evaluating the first argument does not throw.
|
|
Passing the key as a reference achieves just that.</p>
|
|
</div>
|
|
<div class="section" id="when-instantiating-a-pointer-container-with-a-type-t-is-t-then-allowed-to-be-incomplete-at-that-point">
|
|
<h1><a class="toc-backref" href="#id8" name="when-instantiating-a-pointer-container-with-a-type-t-is-t-then-allowed-to-be-incomplete-at-that-point">When instantiating a pointer container with a type <tt class="docutils literal"><span class="pre">T</span></tt>, is <tt class="docutils literal"><span class="pre">T</span></tt> then allowed to be incomplete at that point?</a></h1>
|
|
<p>No. This is a distinct property of <tt class="docutils literal"><span class="pre">shared_ptr</span></tt> which implies some overhead.</p>
|
|
<p>However, one can leave <tt class="docutils literal"><span class="pre">T</span></tt> incomplete in the header file:</p>
|
|
<pre class="literal-block">
|
|
// foo.hpp
|
|
class Foo { ... };
|
|
new_clone( const Foo& ) { ... }
|
|
delete_clone( const Foo* ) { ... }
|
|
|
|
// x.hpp
|
|
class Foo; // Foo is incomplete here
|
|
class X { ptr_deque<Foo> container; ... }
|
|
|
|
// x.cpp
|
|
#include <x.hpp>
|
|
#include <foo.hpp> // now Foo is not incomplete anymore
|
|
...
|
|
</pre>
|
|
</div>
|
|
<div class="section" id="why-do-iterator-range-inserts-give-the-strong-exception-safety-guarantee">
|
|
<h1><a class="toc-backref" href="#id9" name="why-do-iterator-range-inserts-give-the-strong-exception-safety-guarantee">Why do iterator-range inserts give the strong exception-safety guarantee?</a></h1>
|
|
<p>Is this not very inefficient? It is because it is actually affordable to
|
|
do so; the overhead is one heap-allocation which is relatively small
|
|
compared to cloning N objects.</p>
|
|
</div>
|
|
<div class="section" id="what-is-the-polymorphic-class-problem">
|
|
<h1><a class="toc-backref" href="#id10" name="what-is-the-polymorphic-class-problem">What is the <a class="target" id="polymorphic-class-problem" name="polymorphic-class-problem">polymorphic class problem</a>?</a></h1>
|
|
<p>The problem refers to the relatively troublesome way C++ supports Object
|
|
Oriented programming in connection with containers of pointers to
|
|
polymorphic objects. In a language without garbage collection, you end up
|
|
using either a container of pointer pointers or a container that takes
|
|
ownership of the pointers. The hard part is to find a safe, fast and
|
|
elegant solution.</p>
|
|
</div>
|
|
<div class="section" id="are-the-pointer-containers-faster-and-do-they-have-a-better-memory-footprint-than-a-container-of-pointer-pointers">
|
|
<h1><a class="toc-backref" href="#id11" name="are-the-pointer-containers-faster-and-do-they-have-a-better-memory-footprint-than-a-container-of-pointer-pointers">Are the pointer containers faster and do they have a better memory footprint than a container of pointer pointers?</a></h1>
|
|
<p>The short answer is yes: they are faster and they do use less memory; in
|
|
fact, they are the only way to obtain the zero-overhead hallmark of C++.
|
|
Smart pointers usually have one word or more of memory overhead per
|
|
pointer because a reference count must be maintained. And since the
|
|
reference count must be maintained, there is also a runtime-overhead. If
|
|
your objects are big, then the memory overhead is often negligible, but if
|
|
you have many small objects, it is not. Further reading can be found in
|
|
these references: <a class="reference" href="ptr_container.html#references">[11]</a> and <a class="reference" href="ptr_container.html#references">[12]</a>.</p>
|
|
</div>
|
|
<div class="section" id="when-the-stored-pointers-cannot-be-0-how-do-i-allow-this-empty-behavior-anyway">
|
|
<h1><a class="toc-backref" href="#id12" name="when-the-stored-pointers-cannot-be-0-how-do-i-allow-this-empty-behavior-anyway">When the stored pointers cannot be <tt class="docutils literal"><span class="pre">0</span></tt>, how do I allow this "empty" behavior anyway?</a></h1>
|
|
<p>Storing a null-pointer among a list of pointers does not fit well into the Object Oriented paradigm.
|
|
The most elegant design is to use the Null-Object Pattern where one basically makes a concrete
|
|
class with dummy implementations of the virtual functions. See <a class="reference" href="ptr_container.html#references">[13]</a> for details.</p>
|
|
<table class="docutils field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Thorsten Ottosen 2004-2005.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|