2000-04-21 22:33:34 +02:00
|
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
2001-09-18 01:24:40 +02:00
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta HcodeP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
|
|
|
<meta NAME="AUTHOR" CONTENT="pme@gcc.gnu.org (Phil Edwards)">
|
|
|
|
<meta NAME="KEYWORDS" CONTENT="HOWTO, libstdc++, GCC, g++, libg++, STL">
|
|
|
|
<meta NAME="DESCRIPTION" CONTENT="HOWTO for the libstdc++ chapter 20.">
|
|
|
|
<meta NAME="GENERATOR" CONTENT="vi and eight fingers">
|
|
|
|
<title>libstdc++-v3 HOWTO: Chapter 20</title>
|
|
|
|
<link REL=StyleSheet HREF="../lib3styles.css">
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
|
|
|
|
<h1 CLASS="centered"><a name="top">Chapter 20: General Utilities</a></h1>
|
|
|
|
|
|
|
|
<p>Chapter 20 deals with utility classes and functions, such as
|
|
|
|
the oft-debated <code>auto_ptr<></code>.
|
|
|
|
</p>
|
2000-04-21 22:33:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
<!-- ####################################################### -->
|
2001-09-18 01:24:40 +02:00
|
|
|
<hr>
|
|
|
|
<h1>Contents</h1>
|
|
|
|
<ul>
|
|
|
|
<li><a href="#1"><code>auto_ptr</code> is not omnipotent</a>
|
|
|
|
<li><a href="#2"><code>auto_ptr</code> inside container classes</a>
|
|
|
|
<li><a href="#3">Functors</a>
|
|
|
|
<li><a href="#4">Pairs</a>
|
|
|
|
</ul>
|
2000-04-21 22:33:34 +02:00
|
|
|
|
2001-09-18 01:24:40 +02:00
|
|
|
<hr>
|
2000-04-21 22:33:34 +02:00
|
|
|
|
|
|
|
<!-- ####################################################### -->
|
|
|
|
|
2001-09-18 01:24:40 +02:00
|
|
|
<h2><a name="1"><code>auto_ptr</code> is not omnipotent</a></h2>
|
|
|
|
<p>I'm not going to try and explain all of the fun and delicious
|
2000-04-21 22:33:34 +02:00
|
|
|
things that can happen with misuse of the auto_ptr class template
|
|
|
|
(called AP here), nor am I going to try and teach you how to use
|
|
|
|
AP safely in the presence of copying. The AP class is a really
|
|
|
|
nifty idea for a smart pointer, but it is one of the dumbest of
|
|
|
|
all the smart pointers -- and that's fine.
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
|
|
|
<p>AP is not meant to be a supersmart solution to all resource
|
2000-04-21 22:33:34 +02:00
|
|
|
leaks everywhere. Neither is it meant to be an effective form
|
|
|
|
of garbage collection (although it can help, a little bit).
|
2001-09-18 01:24:40 +02:00
|
|
|
And it can <em>not</em> be used for arrays!
|
|
|
|
</p>
|
|
|
|
<p>AP <em>is</em> meant to prevent nasty leaks in the presence of
|
|
|
|
exceptions. That's <em>all</em>. This code is AP-friendly:
|
2000-04-21 22:33:34 +02:00
|
|
|
<PRE>
|
|
|
|
// not a recommend naming scheme, but good for web-based FAQs
|
|
|
|
typedef std::auto_ptr<MyClass> APMC;
|
|
|
|
|
|
|
|
extern function_taking_MyClass_pointer (MyClass*);
|
|
|
|
extern some_throwable_function ();
|
|
|
|
|
|
|
|
void func (int data)
|
|
|
|
{
|
|
|
|
APMC ap (new MyClass(data));
|
|
|
|
|
|
|
|
some_throwable_function(); // this will throw an exception
|
|
|
|
|
|
|
|
function_taking_MyClass_pointer (ap.get());
|
|
|
|
}
|
|
|
|
</PRE>When an exception gets thrown, the instance of MyClass that's
|
2001-09-18 01:24:40 +02:00
|
|
|
been created on the heap will be <code>delete</code>'d as the stack is
|
|
|
|
unwound past <code>func()</code>.
|
|
|
|
</p>
|
|
|
|
<p>Changing that code as follows is <em>not</em> AP-friendly:
|
2000-04-21 22:33:34 +02:00
|
|
|
<PRE>
|
|
|
|
APMC ap (new MyClass[22]);
|
|
|
|
</PRE>You will get the same problems as you would without the use
|
|
|
|
of AP:
|
|
|
|
<PRE>
|
|
|
|
char* array = new char[10]; // array new...
|
|
|
|
...
|
|
|
|
delete array; // ...but single-object delete
|
|
|
|
</PRE>
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
|
|
|
<p>AP cannot tell whether the pointer you've passed at creation points
|
2000-04-21 22:33:34 +02:00
|
|
|
to one or many things. If it points to many things, you are about
|
|
|
|
to die. AP is trivial to write, however, so you could write your
|
2001-09-18 01:24:40 +02:00
|
|
|
own <code>auto_array_ptr</code> for that situation (in fact, this has
|
2001-01-23 18:02:28 +01:00
|
|
|
been done many times; check the mailing lists, Usenet, Boost, etc).
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
|
|
|
<p>Return <a href="#top">to top of page</a> or
|
|
|
|
<a href="../faq/index.html">to the FAQ</a>.
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
<h2><a name="2"><code>auto_ptr</code> inside container classes</a></h2>
|
|
|
|
<p>All of the <a href="../23_containers/howto.html">containers</a>
|
2001-01-23 18:02:28 +01:00
|
|
|
described in the standard library require their contained types
|
|
|
|
to have, among other things, a copy contructor like this:
|
2000-04-21 22:33:34 +02:00
|
|
|
<PRE>
|
2001-01-23 18:02:28 +01:00
|
|
|
struct My_Type
|
|
|
|
{
|
2001-05-30 23:55:05 +02:00
|
|
|
My_Type (My_Type const&);
|
2001-01-23 18:02:28 +01:00
|
|
|
};
|
|
|
|
</PRE>
|
|
|
|
Note the const keyword; the object being copied shouldn't change.
|
2001-09-18 01:24:40 +02:00
|
|
|
The template class <code>auto_ptr</code> (called AP here) does not
|
2001-01-23 18:02:28 +01:00
|
|
|
meet this requirement. Creating a new AP by copying an existing
|
|
|
|
one transfers ownership of the pointed-to object, which means that
|
|
|
|
the AP being copied must change, which in turn means that the
|
|
|
|
copy ctors of AP do not take const objects.
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
|
|
|
<p>The resulting rule is simple: <em>Never ever use a container of
|
|
|
|
auto_ptr objects.</em> The standard says that undefined behavior
|
2001-01-23 18:02:28 +01:00
|
|
|
is the result, but it is guaranteed to be messy.
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
|
|
|
<p>To prevent you from doing this to yourself, the
|
|
|
|
<a href="../19_diagnostics/howto.html#3">concept checks</a> built
|
2001-01-23 18:02:28 +01:00
|
|
|
in to this implementation will issue an error if you try to
|
|
|
|
compile code like this:
|
|
|
|
<PRE>
|
|
|
|
#include <vector>
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
void f()
|
|
|
|
{
|
2001-05-30 23:55:05 +02:00
|
|
|
std::vector< std::auto_ptr<int> > vec_ap_int;
|
2001-01-23 18:02:28 +01:00
|
|
|
}
|
|
|
|
</PRE>
|
2001-05-30 23:55:05 +02:00
|
|
|
Should you try this with the checks enabled, you will see an error.
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
|
|
|
<p>Return <a href="#top">to top of page</a> or
|
|
|
|
<a href="../faq/index.html">to the FAQ</a>.
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
<h2><a name="3">Functors</a></h2>
|
|
|
|
<p>If you don't know what functors are, you're not alone. Many people
|
2000-04-21 22:33:34 +02:00
|
|
|
get slightly the wrong idea. In the interest of not reinventing
|
|
|
|
the wheel, we will refer you to the introduction to the functor
|
|
|
|
concept written by SGI as part of their STL, in
|
2001-09-18 01:24:40 +02:00
|
|
|
<a href="http://www.sgi.com/Technology/STL/functors.html">their
|
|
|
|
http://www.sgi.com/Technology/STL/functors.html</a>.
|
|
|
|
</p>
|
|
|
|
<p>Return <a href="#top">to top of page</a> or
|
|
|
|
<a href="../faq/index.html">to the FAQ</a>.
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
<h2><a name="4">Pairs</a></h2>
|
|
|
|
<p>The <code>pair<T1,T2></code> is a simple and handy way to
|
2000-04-21 22:33:34 +02:00
|
|
|
carry around a pair of objects. One is of type T1, and another of
|
|
|
|
type T2; they may be the same type, but you don't get anything
|
|
|
|
extra if they are. The two members can be accessed directly, as
|
2001-09-18 01:24:40 +02:00
|
|
|
<code>.first</code> and <code>.second</code>.
|
|
|
|
</p>
|
|
|
|
<p>Construction is simple. The default ctor initializes each member
|
2000-04-21 22:33:34 +02:00
|
|
|
with its respective default ctor. The other simple ctor,
|
|
|
|
<PRE>
|
|
|
|
pair (const T1& x, const T2& y);
|
2001-09-18 01:24:40 +02:00
|
|
|
</PRE>does what you think it does, <code>first</code> getting <code>x</code>
|
|
|
|
and <code>second</code> getting <code>y</code>.
|
|
|
|
</p>
|
|
|
|
<p>There is a copy constructor, but it requires that your compiler
|
2000-04-21 22:33:34 +02:00
|
|
|
handle member function templates:
|
|
|
|
<PRE>
|
|
|
|
template <class U, class V> pain (const pair<U,V>& p);
|
|
|
|
</PRE>The compiler will convert as necessary from U to T1 and from
|
|
|
|
V to T2 in order to perform the respective initializations.
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
|
|
|
<p>The comparison operators are done for you. Equality
|
|
|
|
of two <code>pair<T1,T2></code>s is defined as both <code>first</code>
|
|
|
|
members comparing equal and both <code>second</code> members comparing
|
2000-04-21 22:33:34 +02:00
|
|
|
equal; this simply delegates responsibility to the respective
|
2001-09-18 01:24:40 +02:00
|
|
|
<code>operator==</code> functions (for types like MyClass) or builtin
|
2000-04-21 22:33:34 +02:00
|
|
|
comparisons (for types like int, char, etc).
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
2001-09-26 01:51:17 +02:00
|
|
|
<a name="pairlt">
|
2001-09-18 01:24:40 +02:00
|
|
|
<p>The less-than operator is a bit odd the first time you see it. It
|
2000-04-21 22:33:34 +02:00
|
|
|
is defined as evaluating to:
|
|
|
|
<PRE>
|
|
|
|
x.first < y.first ||
|
|
|
|
( !(y.first < x.first) && x.second < y.second )
|
|
|
|
</PRE>
|
2001-09-18 01:24:40 +02:00
|
|
|
The other operators are not defined using the <code>rel_ops</code>
|
2000-04-21 22:33:34 +02:00
|
|
|
functions above, but their semantics are the same.
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
2001-09-26 01:51:17 +02:00
|
|
|
</a>
|
2001-09-18 01:24:40 +02:00
|
|
|
<p>Finally, there is a template function called <code>make_pair</code>
|
2000-04-21 22:33:34 +02:00
|
|
|
that takes two references-to-const objects and returns an
|
|
|
|
instance of a pair instantiated on their respective types:
|
|
|
|
<PRE>
|
|
|
|
pair<int,MyClass> p = make_pair(4,myobject);
|
|
|
|
</PRE>
|
2001-09-18 01:24:40 +02:00
|
|
|
</p>
|
|
|
|
<p>Return <a href="#top">to top of page</a> or
|
|
|
|
<a href="../faq/index.html">to the FAQ</a>.
|
|
|
|
</p>
|
2000-04-21 22:33:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ####################################################### -->
|
|
|
|
|
2001-09-18 01:24:40 +02:00
|
|
|
<hr>
|
|
|
|
<P CLASS="fineprint"><em>
|
2000-04-21 22:33:34 +02:00
|
|
|
Comments and suggestions are welcome, and may be sent to
|
2001-09-18 01:24:40 +02:00
|
|
|
<a href="mailto:libstdc++@gcc.gnu.org">the mailing list</a>.
|
|
|
|
</em></p>
|
2000-04-21 22:33:34 +02:00
|
|
|
|
|
|
|
|
2001-09-18 01:24:40 +02:00
|
|
|
</body>
|
|
|
|
</html>
|