| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774 |
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <meta http-equiv="Content-Language" content="en-us">
- <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
- <meta name="GENERATOR" content="Microsoft FrontPage 6.0">
- <meta name="Author" content="Kevlin Henney">
- <meta name="KeyWords" content=
- "C++, Reference Counting, Advanced Techniques, Smart Pointers, Patterns">
- <title>Counted Body Techniques</title>
- </head>
- <body bgcolor="#FFFFFF" text="#000000">
- <h1 align="center"><i><font size="+4">Counted Body Techniques</font></i></h1>
- <center>
- <p><b><font size="+1"><a href="../people/kevlin_henney.htm">Kevlin Henney</a><br></font>
- (<a href=
- "mailto:kevlin@acm.org">kevlin@acm.org</a>, <a href=
- "mailto:khenney@qatraining.com">khenney@qatraining.com</a>)</b></p>
- </center>
- <div style="margin-left: 2em">
- <p>Reference counting techniques? Nothing new, you might think. Every good
- C++ text that takes you to an intermediate or advanced level will
- introduce the concept. It has been explored with such thoroughness in the
- past that you might be forgiven for thinking that everything that can be
- said has been said. Well, let's start from first principles and see if we
- can unearth something new....</p>
- </div>
- <hr width="100%">
- <h2>And then there were none...</h2>
- <div style="margin-left: 2em">
- <p>The principle behind reference counting is to keep a running usage
- count of an object so that when it falls to zero we know the object is
- unused. This is normally used to simplify the memory management for
- dynamically allocated objects: keep a count of the number of references
- held to that object and, on zero, delete the object.</p>
- <p>How to keep a track of the number of users of an object? Well, normal
- pointers are quite dumb, and so an extra level of indirection is required
- to manage the count. This is essentially the P<font size="-1">ROXY</font>
- pattern described in <i>Design Patterns</i> [Gamma, Helm, Johnson &
- Vlissides, Addison-Wesley, <font size="-1">ISBN</font> 0-201-63361-2]. The
- intent is given as</p>
- <div style="margin-left: 2em">
- <p><i>Provide a surrogate or placeholder for another object to control
- access to it.</i></p>
- </div>
- <p>Coplien [<i>Advanced C++ Programming Styles and Idioms</i>,
- Addison-Wesley, <font size="-1">ISBN</font> 0-201-56365-7] defines a set
- of idioms related to this essential separation of a handle and a body
- part. The <i>Taligent Guide to Designing Programs</i> [Addison-Wesley,
- <font size="-1">ISBN</font> 0-201-40888-0] identifies a number of specific
- categories for proxies (aka surrogates). Broadly speaking they fall into
- two general categories:</p>
- <ul>
- <li><i>Hidden</i>: The handle is the object of interest, hiding the body
- itself. The functionality of the handle is obtained by delegation to the
- body, and the user of the handle is unaware of the body. Reference
- counted strings offer a transparent optimisation. The body is shared
- between copies of a string until such a time as a change is needed, at
- which point a copy is made. Such a C<font size=
- "-1">OPY</font> <font size="-1">ON</font> W<font size="-1">RITE</font>
- pattern (a specialisation of L<font size="-1">AZY</font> E<font size=
- "-1">VALUATION</font>) requires the use of a hidden reference counted
- body.</li>
- <li><i>Explicit</i>: Here the body is of interest and the handle merely
- provides intelligence for its access and housekeeping. In C++ this is
- often implemented as the S<font size="-1">MART</font> P<font size=
- "-1">OINTER</font> idiom. One such application is that of reference
- counted smart pointers that collaborate to keep a count of an object,
- deleting it when the count falls to zero.</li>
- </ul>
- </div>
- <hr width="100%">
- <h2>Attached vs detached</h2>
- <div style="margin-left: 2em">
- <p>For reference counted smart pointers there are two places the count can
- exist, resulting in two different patterns, both outlined in
- <i>Software Patterns</i> [Coplien, SIGS, <font size="-1">ISBN</font>
- 0-884842-50-X]:</p>
- <ul>
- <li>C<font size="-1">OUNTED</font> B<font size="-1">ODY</font> or A<font size="-1">TTACHED</font>
- C<font size="-1">OUNTED</font>
- H<font size="-1">ANDLE</font>/B<font size="-1">ODY</font> places the
- count within the object being counted. The benefits are that
- countability is a part of the object being counted, and that reference
- counting does not require an additional object. The drawbacks are
- clearly that this is intrusive, and that the space for the reference
- count is wasted when the object is not heap based. Therefore the
- reference counting ties you to a particular implementation and style of
- use.</li>
- <li>D<font size="-1">ETACHED</font> C<font size="-1">OUNTED</font>
- H<font size="-1">ANDLE</font>/B<font size="-1">ODY</font> places the
- count outside the object being counted, such that they are handled
- together. The clear benefit of this is that this technique is completely
- unintrusive, with all of the intelligence and support apparatus in the
- smart pointer, and therefore can be used on classes created
- independently of the reference counted pointer. The main disadvantage is
- that frequent use of this can lead to a proliferation of small objects,
- i.e. the counter, being created on the heap.</li>
- </ul>
- <p>Even with this simple analysis, it seems that the D<font size=
- "-1">ETACHED</font> C<font size="-1">OUNTED</font> H<font size=
- "-1">ANDLE</font>/B<font size="-1">ODY</font> approach is ahead. Indeed,
- with the increasing use of templates this is often the favourite, and is
- the principle behind the common - but not standard - <tt><font size=
- "+1">counted_ptr</font></tt>. <i>[The Boost name is <a href=
- "../libs/smart_ptr/shared_ptr.htm"><tt><font size=
- "+1">shared_ptr</font></tt></a> rather than <tt><font size=
- "+1">counted_ptr</font></tt>.]</i></p>
- <p>A common implementation of C<font size="-1">OUNTED</font> B<font size=
- "-1">ODY</font> is to provide the counting mechanism in a base class that
- the counted type is derived from. Either that, or the reference counting
- mechanism is provided anew for each class that needs it. Both of these
- approaches are unsatisfactory because they are quite closed, coupling a
- class into a particular framework. Added to this the non-cohesiveness of
- having the count lying dormant in a non-counted object, and you get the
- feeling that excepting its use in widespread object models such as COM and
- CORBA the C<font size="-1">OUNTED</font> B<font size="-1">ODY</font>
- approach is perhaps only of use in specialised situations.</p>
- </div>
- <hr width="100%">
- <h2>A requirements based approach</h2>
- <div style="margin-left: 2em">
- <p>It is the question of openness that convinced me to revisit the
- problems with the C<font size="-1">OUNTED</font> B<font size=
- "-1">ODY</font> idiom. Yes, there is a certain degree of intrusion
- expected when using this idiom, but is there anyway to minimise this and
- decouple the choice of counting mechanism from the smart pointer type
- used?</p>
- <p>In recent years the most instructive body of code and specification for
- constructing open general purpose components has been the Stepanov and
- Lee's STL (Standard Template Library), now part of the C++ standard
- library. The STL approach makes extensive use of compile time polymorphism
- based on well defined operational requirements for types. For instance,
- each container, contained and iterator type is defined by the operations
- that should be performable on an object of that type, often with
- annotations describing additional constraints. Compile time polymorphism,
- as its name suggests, resolves functions at compile time based on function
- name and argument usage, i.e. overloading. This is less intrusive,
- although less easily diagnosed if incorrect, than runtime poymorphism that
- is based on types, names and function signatures.</p>
- <p>This requirements based approach can be applied to reference counting.
- The operations we need for a type to be <i>Countable</i> are loosely:</p>
- <ul>
- <li>An <tt><font size="+1">acquire</font></tt> operation that registers
- interest in a <i>Countable</i> object.</li>
- <li>A <tt><font size="+1">release</font></tt> operation unregisters
- interest in a <i>Countable</i> object.</li>
- <li>An <tt><font size="+1">acquired</font></tt> query that returns
- whether or not a <i>Countable</i> object is currently acquired.</li>
- <li>A <tt><font size="+1">dispose</font></tt> operation that is
- responsible for disposing of an object that is no longer acquired.</li>
- </ul>
- <p>Note that the count is deduced as a part of the abstract state of this
- type, and is not mentioned or defined in any other way. The openness of
- this approach derives in part from the use of global functions, meaning
- that no particular member functions are implied; a perfect way to wrap up
- an existing counted body class without modifying the class itself. The
- other aspect to the openness comes from a more precise specification of
- the operations.</p>
- <p>For a type to be <i>Countable</i> it must satisfy the following
- requirements, where <tt><font size="+1">ptr</font></tt> is a non-null
- pointer to a single object (i.e. not an array) of the type, and
- <i><tt><font size="+1">#function</font></tt></i> indicates number of calls
- to <tt><font size="+1"><i>function(</i>ptr<i>)</i></font></tt>:</p>
- <center>
- <table border="1" cellspacing="2" cellpadding="2" summary="">
- <tr>
- <td><i>Expression</i></td>
- <td><i>Return type</i></td>
- <td><i>Semantics and notes</i></td>
- </tr>
- <tr>
- <td><tt><font size="+1">acquire(ptr)</font></tt></td>
- <td>no requirement</td>
- <td><i>post</i>: <tt><font size="+1">acquired(ptr)</font></tt></td>
- </tr>
- <tr>
- <td><tt><font size="+1">release(ptr)</font></tt></td>
- <td>no requirement</td>
- <td><i>pre</i>: <tt><font size="+1">acquired(ptr)<br></font></tt>
- <i>post</i>: <tt><font size="+1">acquired(ptr) == #acquire -
- #release</font></tt></td>
- </tr>
- <tr>
- <td><tt><font size="+1">acquired(ptr)</font></tt></td>
- <td>convertible to <tt><font size="+1">bool</font></tt></td>
- <td><i>return</i>: <tt><font size="+1">#acquire > #release</font></tt></td>
- </tr>
- <tr>
- <td><tt><font size="+1">dispose(ptr, ptr)</font></tt></td>
- <td>no requirement</td>
- <td><i>pre</i>: <tt><font size="+1">!acquired(ptr)<br></font></tt>
- <i>post</i>: <tt><font size="+1">*ptr</font></tt> no longer usable</td>
- </tr>
- </table>
- </center>
- <p>Note that the two arguments to <tt><font size="+1">dispose</font></tt>
- are to support selection of the appropriate type safe version of the
- function to be called. In the general case the intent is that the first
- argument determines the type to be deleted, and would typically be
- templated, while the second selects which template to use, e.g. by
- conforming to a specific base class.</p>
- <p>In addition the following requirements must also be satisfied, where
- <tt><font size="+1">null</font></tt> is a null pointer to the
- <i>Countable</i> type:</p>
- <center>
- <table border="1" summary="">
- <tr>
- <td><i>Expression</i></td>
- <td><i>Return type</i></td>
- <td><i>Semantics and notes</i></td>
- </tr>
- <tr>
- <td><tt><font size="+1">acquire(null)</font></tt></td>
- <td>no requirement</td>
- <td><i>action</i>: none</td>
- </tr>
- <tr>
- <td><tt><font size="+1">release(null)</font></tt></td>
- <td>no requirement</td>
- <td><i>action</i>: none</td>
- </tr>
- <tr>
- <td><tt><font size="+1">acquired(null)</font></tt></td>
- <td>convertible to <tt><font size="+1">bool</font></tt></td>
- <td><i>return</i>: <tt><font size="+1">false</font></tt></td>
- </tr>
- <tr>
- <td><tt><font size="+1">dispose(null, null)</font></tt></td>
- <td>no requirement</td>
- <td><i>action</i>: none</td>
- </tr>
- </table>
- </center>
- <p>Note that there are no requirements on these functions in terms of
- exceptions thrown or not thrown, except that if exceptions are thrown the
- functions themselves should be exception safe.</p>
- </div>
- <hr width="100%">
- <h2>Getting smart</h2>
- <div style="margin-left: 2em">
- <p>Given the <i>Countable</i> requirements for a type, it is possible to
- define a generic smart pointer type that uses them for reference counting:</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>template<typename countable_type>
- class countable_ptr
- {
- public: // construction and destruction
- explicit countable_ptr(countable_type *);
- countable_ptr(const countable_ptr &);
- ~countable_ptr();
- public: // access
- countable_type *operator->() const;
- countable_type &operator*() const;
- countable_type *get() const;
- public: // modification
- countable_ptr &clear();
- countable_ptr &assign(countable_type *);
- countable_ptr &assign(const countable_ptr &);
- countable_ptr &operator=(const countable_ptr &);
- private: // representation
- countable_type *body;
- };
- </tt>
- </pre>
- </div>
- <p>The interface to this class has been kept intentionally simple, e.g.
- member templates and <tt><font size="+1">throw</font></tt> specs have been
- omitted, for exposition. The majority of the functions are quite simple in
- implementation, relying very much on the <tt><font size=
- "+1">assign</font></tt> member as a keystone function:</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>template<typename countable_type>
- countable_ptr<countable_type>::countable_ptr(countable_type *initial)
- : body(initial)
- {
- acquire(body);
- }
- template<typename countable_type>
- countable_ptr<countable_type>::countable_ptr(const countable_ptr &other)
- : body(other.body)
- {
- acquire(body);
- }
- template<typename countable_type>
- countable_ptr<countable_type>::~countable_ptr()
- {
- clear();
- }
- template<typename countable_type>
- countable_type *countable_ptr<countable_type>::operator->() const
- {
- return body;
- }
- template<typename countable_type>
- countable_type &countable_ptr<countable_type>::operator*() const
- {
- return *body;
- }
- template<typename countable_type>
- countable_type *countable_ptr<countable_type>::get() const
- {
- return body;
- }
- template<typename countable_type>
- countable_ptr<countable_type> &countable_ptr<countable_type>::clear()
- {
- return assign(0);
- }
- template<typename countable_type>
- countable_ptr<countable_type> &countable_ptr<countable_type>::assign(countable_type *rhs)
- {
- // set to rhs (uses Copy Before Release idiom which is self assignment safe)
- acquire(rhs);
- countable_type *old_body = body;
- body = rhs;
- // tidy up
- release(old_body);
- if(!acquired(old_body))
- {
- dispose(old_body, old_body);
- }
- return *this;
- }
- template<typename countable_type>
- countable_ptr<countable_type> &countable_ptr<countable_type>::assign(const countable_ptr &rhs)
- {
- return assign(rhs.body);
- }
- template<typename countable_type>
- countable_ptr<countable_type> &countable_ptr<countable_type>::operator=(const countable_ptr &rhs)
- {
- return assign(rhs);
- }
- </tt>
- </pre>
- </div>
- </div>
- <hr width="100%">
- <h2>Public accountability</h2>
- <div style="margin-left: 2em">
- <p>Conformance to the requirements means that a type can be used with
- <tt><font size="+1">countable_ptr</font></tt>. Here is an implementation
- mix-in class (<i>mix-imp</i>) that confers countability on its derived
- classes through member functions. This class can be used as a class
- adaptor:</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>class countability
- {
- public: // manipulation
- void acquire() const;
- void release() const;
- size_t acquired() const;
- protected: // construction and destruction
- countability();
- ~countability();
- private: // representation
- mutable size_t count;
- private: // prevention
- countability(const countability &);
- countability &operator=(const countability &);
- };
- </tt>
- </pre>
- </div>
- <p>Notice that the manipulation functions are <tt><font size=
- "+1">const</font></tt> and that the <tt><font size="+1">count</font></tt>
- member itself is <tt><font size="+1">mutable</font></tt>. This is because
- countability is not a part of an object's abstract state: memory
- management does not depend on the <tt><font size=
- "+1">const</font></tt>-ness or otherwise of an object. I won't include the
- definitions of the member functions here as you can probably guess them:
- increment, decrement and return the current count, respectively for the
- manipulation functions. In a multithreaded environment you should ensure
- that such read and write operations are atomic.</p>
- <p>So how do we make this class <i>Countable</i>? A simple set of
- forwarding functions does the job:</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>void acquire(const countability *ptr)
- {
- if(ptr)
- {
- ptr->acquire();
- }
- }
- void release(const countability *ptr)
- {
- if(ptr)
- {
- ptr->release();
- }
- }
- size_t acquired(const countability *ptr)
- {
- return ptr ? ptr->acquired() : 0;
- }
- template<class countability_derived>
- void dispose(const countability_derived *ptr, const countability *)
- {
- delete ptr;
- }
- </tt>
- </pre>
- </div>
- <p>Any type that now derives from <tt><font size=
- "+1">countability</font></tt> may now be used with <tt><font size=
- "+1">countable_ptr</font></tt>:</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>class example : public countability
- {
- ...
- };
- void simple()
- {
- countable_ptr<example> ptr(new example);
- countable_ptr<example> qtr(ptr);
- ptr.clear(); // set ptr to point to null
- } // allocated object deleted when qtr destructs
- </tt>
- </pre>
- </div>
- </div>
- <hr width="100%">
- <h2>Runtime mixin</h2>
- <div style="margin-left: 2em">
- <p>The challenge is to apply C<font size="-1">OUNTED</font> B<font size=
- "-1">ODY</font> in a non-intrusive fashion, such that there is no overhead
- when an object is not counted. What we would like to do is confer this
- capability on a per object rather than on a per class basis. Effectively
- we are after <i>Countability</i> on any object, i.e. anything pointed to
- by a <tt><font size="+1">void *</font></tt>! It goes without saying that <tt><font size="+1">
- void</font></tt> is perhaps the least committed of any type.</p>
- <p>The forces to resolve on this are quite interesting, to say the least.
- Interesting, but not insurmountable. Given that the class of a runtime
- object cannot change dynamically in any well defined manner, and the
- layout of the object must be fixed, we have to find a new place and time
- to add the counting state. The fact that this must be added only on heap
- creation suggests the following solution:</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>struct countable_new;
- extern const countable_new countable;
- void *operator new(size_t, const countable_new &);
- void operator delete(void *, const countable_new &);</tt>
- </pre>
- </div>
- <p>We have overloaded <tt><font size="+1">operator new</font></tt> with a
- dummy argument to distinguish it from the regular global <tt><font size=
- "+1">operator new</font></tt>. This is comparable to the use of the
- <tt><font size="+1">std::nothrow_t</font></tt> type and <tt><font size=
- "+1">std::nothrow</font></tt> object in the standard library. The
- placement <tt><font size="+1">operator delete</font></tt> is there to
- perform any tidy up in the event of failed construction. Note that this is
- not yet supported on all that many compilers.</p>
- <p>The result of a <tt><font size="+1">new</font></tt> expression using
- <tt><font size="+1">countable</font></tt> is an object allocated on the
- heap that has a header block that holds the count, i.e. we have extended
- the object by prefixing it. We can provide a couple of features in an
- anonymous namespace (not shown) in the implementation file for for
- supporting the count and its access from a raw pointer:</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>struct count
- {
- size_t value;
- };
- count *header(const void *ptr)
- {
- return const_cast<count *>(static_cast<const count *>(ptr) - 1);
- }
- </tt>
- </pre>
- </div>
- <p>An important constraint to observe here is the alignment of
- <tt><font size="+1">count</font></tt> should be such that it is suitably
- aligned for any type. For the definition shown this will be the case on
- almost all platforms. However, you may need to add a padding member for
- those that don't, e.g. using an anonymous <tt><font size=
- "+1">union</font></tt> to coalign <tt><font size="+1">count</font></tt>
- and the most aligned type. Unfortunately, there is no portable way of
- specifying this such that the minimum alignment is also observed - this is
- a common problem when specifying your own allocators that do not directly
- use the results of either <tt><font size="+1">new</font></tt> or
- <tt><font size="+1">malloc</font></tt>.</p>
- <p>Again, note that the count is not considered to be a part of the
- logical state of the object, and hence the conversion from
- <tt><font size="+1">const</font></tt> to non-<tt><font size=
- "+1">const</font></tt> - <tt><font size="+1">count</font></tt> is in
- effect a <tt><font size="+1">mutable</font></tt> type.</p>
- <p>The allocator functions themselves are fairly straightforward:</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>void *operator new(size_t size, const countable_new &)
- {
- count *allocated = static_cast<count *>(::operator new(sizeof(count) + size));
- *allocated = count(); // initialise the header
- return allocated + 1; // adjust result to point to the body
- }
- void operator delete(void *ptr, const countable_new &)
- {
- ::operator delete(header(ptr));
- }
- </tt>
- </pre>
- </div>
- <p>Given a correctly allocated header, we now need the <i>Countable</i>
- functions to operate on <tt><font size="+1">const void *</font></tt> to
- complete the picture:</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>void acquire(const void *ptr)
- {
- if(ptr)
- {
- ++header(ptr)->value;
- }
- }
- void release(const void *ptr)
- {
- if(ptr)
- {
- --header(ptr)->value;
- }
- }
- size_t acquired(const void *ptr)
- {
- return ptr ? header(ptr)->value : 0;
- }
- template<typename countable_type>
- void dispose(const countable_type *ptr, const void *)
- {
- ptr->~countable_type();
- operator delete(const_cast<countable_type *>(ptr), countable);
- }
- </tt>
- </pre>
- </div>
- <p>The most complex of these is the <tt><font size=
- "+1">dispose</font></tt> function that must ensure that the correct type
- is destructed and also that the memory is collected from the correct
- offset. It uses the value and type of first argument to perform this
- correctly, and the second argument merely acts as a strategy selector,
- i.e. the use of <tt><font size="+1">const void *</font></tt>
- distinguishes it from the earlier dispose shown for <tt><font size=
- "+1">const countability *</font></tt>.</p>
- </div>
- <hr width="100%">
- <h2>Getting smarter</h2>
- <div style="margin-left: 2em">
- <p>Now that we have a way of adding countability at creation for objects
- of any type, what extra is needed to make this work with the
- <tt><font size="+1">countable_ptr</font></tt> we defined earlier? Good
- news: nothing!</p>
- <div style="margin-left: 2em">
- <pre>
- <tt>class example
- {
- ...
- };
- void simple()
- {
- countable_ptr<example> ptr(new(countable) example);
- countable_ptr<example> qtr(ptr);
- ptr.clear(); // set ptr to point to null
- } // allocated object deleted when qtr destructs
- </tt>
- </pre>
- </div>
- <p>The <tt><font size="+1">new(countable)</font></tt> expression defines a
- different policy for allocation and deallocation and, in common with other
- allocators, any attempt to mix your allocation policies, e.g. call
- <tt><font size="+1">delete</font></tt> on an object allocated with
- <tt><font size="+1">new(countable)</font></tt>, results in undefined
- behaviour. This is similar to what happens when you mix <tt><font size=
- "+1">new[]</font></tt> with <tt><font size="+1">delete</font></tt> or
- <tt><font size="+1">malloc</font></tt> with <tt><font size=
- "+1">delete</font></tt>. The whole point of <i>Countable</i> conformance
- is that <i>Countable</i> objects are used with <tt><font size=
- "+1">countable_ptr</font></tt>, and this ensures the correct use.</p>
- <p>However, accidents will happen, and inevitably you may forget to
- allocate using <tt><font size="+1">new(countable)</font></tt> and instead
- use <tt><font size="+1">new</font></tt>. This error and others can be
- detected in most cases by extending the code shown here to add a check
- member to the <tt><font size="+1">count</font></tt>, validating the check
- on every access. A benefit of ensuring clear separation between header and
- implementation source files means that you can introduce a checking
- version of this allocator without having to recompile your code.</p>
- </div>
- <hr width="100%">
- <h2>Conclusion</h2>
- <div style="margin-left: 2em">
- <p>There are two key concepts that this article has introduced:</p>
- <ul>
- <li>The use of a generic requirements based approach to simplify and
- adapt the use of the C<font size="-1">OUNTED</font> B<font size=
- "-1">ODY</font> pattern.</li>
- <li>The ability, through control of allocation, to dynamically and
- non-intrusively add capabilities to fixed types using the R<font size=
- "-1">UNTIME</font> M<font size="-1">IXIN</font> pattern.</li>
- </ul>
- <p>The application of the two together gives rise to a new variant of the
- essential C<font size="-1">OUNTED</font> B<font size="-1">ODY</font>
- pattern, U<font size="-1">NINTRUSIVE</font> C<font size=
- "-1">OUNTED</font> B<font size="-1">ODY</font>. You can take this theme
- even further and contrive a simple garbage collection system for C++.</p>
- <p>The complete code for <tt><font size="+1">countable_ptr</font></tt>,
- <tt><font size="+1">countability</font></tt>, and the <tt><font size=
- "+1">countable new</font></tt> is also available.</p>
- </div>
- <div align="right">
- <hr width="100%">
- <font size="-1"><i>First published in</i> <a href=
- "http://www.accu.org/c++sig/public/Overload.html">Overload</a> <i>25,
- April 1998, ISSN 1354-3172</i></font>
- </div>
-
- <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
- "http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional"
- height="31" width="88"></a></p>
- <p>Revised
- <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->04 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38514" --></p>
- <p><i>Copyright © 1998-1999 Kevlin Henney</i></p>
- <p><i>Distributed under the Boost Software License, Version 1.0. (See
- accompanying file <a href="../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
- at <a href=
- "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
- </body>
- </html>
|