    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Implementing the Observer Pattern in C++ - Part 2</title>
        <link>https://members.accu.org/index.php/journals/2007</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #53 - Feb 2003 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c193/">53</a>
                    (9)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c193-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c193+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Implementing the Observer Pattern in C++ - Part 2</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 08 February 2003 12:35:11 +00:00 or Sat, 08 February 2003 12:35:11 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<p>In part 1 of this article I presented an Event/Callback library intended to support the Observer pattern and hinted that it had some limitations. The library was based on the following Event class template:</p>

<table class="sidebartable">
<tr>
<td>
<pre class="programlisting">template&lt;typename Arg&gt;
class Event {
public:
    // Iterator type definition.
    typedef ... iterator;

    // Destroy an Event.
    ~Event();

    // Attach a simple function to an Event.
    template&lt;typename Function&gt;
    iterator attach(Function);

    // Attach a member function to an Event.
    template&lt;class Pointer, typename Member&gt;
    iterator attach(Pointer, Member);

    // Detach a function from an Event.
    void detach(iterator);

    // Notify Observers that an Event has occurred.
    void notify(Arg) const;
private:
    ...
};
</pre>
</td>
</tr>
<tr>
<td class="title">Listing 1 - The Event&lt;&gt; class interface</td>
</tr>
</table>

<p>In this version of the library an Event is essentially a list of polymorphic function objects (callbacks) owned by the Event. The <code>attach()</code> functions create a callback and add it to the list; the <code>detach()</code> function removes a callback from the list and destroys it. The <code>notify()</code> function simply calls each callback in the list passing a single parameter.</p>
<h2>Logic Gates</h2>
<p>The company I work for supplies industrial control systems. These systems are based on general purpose hardware components and highly configurable software. For example, we build â€œpodsâ€ that are part of underwater pipeline repair tools. The pods are designed to withstand conditions on the sea bed, but they contain general purpose I/O boards. As far as the software is concerned a pod is little more than a collection of digital and analogue inputs/outputs. Pods can be used to monitor and control tools for lifting and lowering sections of pipeline, cutting the pipe, welding pipes together and all sorts of ancillary operations. Different tool sets are used for different jobs and the software has to be configured accordingly. The configuration information is held in a database.</p>
<p>The database stores information that defines the control logic. For example, the data may indicate that a particular button on a control panel turns on a lamp or controls a pump. At present this is rather inflexible, so we considered using arbitrary networks of logic gates as a more general solution. The database would store these networks in the form of tables for each of the basic types of logic gate (NOT, AND, OR), plus a table specifying connections between the inputs and outputs of these logic gates. (Analogue inputs and outputs are not considered, here, but a similar mechanism can be envisaged for them.)</p>
<p>On start-up the control system software would create some logic gate objects and connect their inputs and outputs as specified in the database. The natural way to implement the connections was to use our existing Event/Callback library, which is based on the Event class template sketched in Listing1. An output is an Event and an input is a function that can be attached to such an Event.</p>
<h2>A Worry</h2>
<p>As always, there is a down side to this design. Because AND, OR and NOT gates are very simple a large number of them may be needed for practical control systems. And, because the software only â€œseesâ€ an arbitrary network, it is not possible to control the complexity of connections by using a hierarchical data structure. The logic gates almost have to be stored as simple collections. And collections require value semantics. Unfortunately, the Event classes, and hence the logic gates that contain them, donâ€™t have the required semantics - in particular, they can not be copied safely.</p>
<p>There are two well-known ways to resolve this problem. Either the Event classes are changed so that they can be safely stored in containers or some sort of value-like handles to Events are stored instead of the Events themselves.</p>
<h2>Copyable Events</h2>
<p>It is fairly straightforward to change the Event template so that Events can be stored in standard containers. Objects in standard containers are required to be Assignable and CopyConstructible, so implementing a suitable copy assignment operator and copy constructor will do the trick. Since an Event owns its callbacks, making a copy involves cloning the callbacks, which can be done using the â€œvirtual constructorâ€ technique described in [1].</p>
<p>So, yes, we can make Events copyable, but is it a good idea? Well, not really, because it creates another, less tractable, problem.</p>
<p>Consider the following scenario:</p>
<ol>
<li>An Event is added to a container.</li>
<li>A callback is attached to the Event.</li>
<li>Another Event is added to the container.</li>
<li>The callback is detached from the original Event.</li>
</ol>
<p>The program in Listing 2 illustrates this scenario.</p>

<table class="sidebartable">
<tr>
<td>
<pre class="programlisting">#include &lt;vector&gt;
#include &quot;Event.hpp&quot;

void f(int) { return; }

int main()
{
    std::vector&lt; Event&lt;int&gt; &gt; events;
    events.push_back(Event&lt;int&gt;());                 // Step 1

    Event&lt;int&gt;::iterator i0 = events[0].attach(f);  // Step 2

    events.push_back(Event&lt;int&gt;());                 // Step 3

    Event&lt;int&gt;::iterator i1 = events[1].attach(f);
    events[1].detach(i1);
    events[0].detach(i0);                           // Step 4

    return 0;
}
</pre>
</td>
</tr>
<tr>
<td class="title">Listing 2 - Invalidating iterators</td>
</tr>
</table>

<p>With the implementation of std::vector that I am using, step 4 fails because step 3 invalidates the iterator created in step 2. In this case, the iterator is invalidated when the container it points into (an Event) is moved from one memory location to another. C++ doesnâ€™t provide a mechanism for defining â€˜moveâ€™ semantics, so the vector copies the original Event and destroys the original, leaving a dangling iterator.</p>
<p>It is the application programâ€™s responsibility to avoid this problem. Possible fixes include: reserving space in the vector for all the events before attaching their callbacks; using a container whose <code>push_back()</code> function doesnâ€™t move existing elements; and attaching the callbacks only after all events have been added to the vector. In the tiny program shown here we can simply swap steps 2 and 3, but in general there may not be an easy fix.</p>
<p>There is one other avenue we might explore in our attempt to store Events in standard containers without placing a burden on the client code. Suppose we change the Event classes so that they keep track of the iterators returned by <code>attach()</code>. Then, when an event is moved all iterators pointing to that event can be adjusted accordingly. But the appropriate â€˜moveâ€™ semantics must be implemented using the copy constructor, assignment operator and destructor. These functions must adjust iterators pointing to the original Event when it is moved, but not when it is merely copied, assigned or destroyed. I imagine this can be achieved, but it certainly makes the Event classes less efficient and less cohesive. There has to be a better way.</p>
<h2>Copyable Event Handles</h2>
<p>If making Events copyable gets us into murky waters, perhaps we should be using non-copyable events and accessing them via copyable handles. The handles can be stored in standard containers and the Event iterators will remain valid when the handles are moved.</p>
<p>The Boost [2] shared pointer is a suitable candidate for a copyable Event handle. It is a smart pointer template with shared ownership semantics. All shared pointers pointing to the same target object share ownership of that object, so that the target object is destroyed when its last shared pointer is destroyed.</p>
<p>Using this technique the code in Listing 2 becomes the program in Listing 3.</p>

<table class="sidebartable">
<tr>
<td>
<pre class="programlisting">#include &lt;vector&gt;
#include &lt;boost/shared_ptr.hpp&gt;
#include &quot;Event.hpp&quot;

void f(int) { return; }

typedef boost::shared_ptr&lt; Event&lt;int&gt; &gt; Handle;

int main()
{
    std::vector&lt;Handle&gt; events;

    events.push_back(Handle(new Event&lt;int&gt;()));
    Event&lt;int&gt;::iterator i0 = events[0]-&gt;attach(f);

    events.push_back(Handle(new Event&lt;int&gt;()));
    Event&lt;int&gt;::iterator i1 = events[1]-&gt;attach(f);

    events[1]-&gt;detach(i1);
    events[0]-&gt;detach(i0);

    return 0;
}
</pre>
</td>
</tr>
<tr>
<td class="title">Listing 3 - Using copyable handles.</td>
</tr>
</table>

<p>Although this solves the copyability problem, it comes at a cost. Events are now allocated on the heap, the shared pointers have some house-keeping to do and there is an extra level of indirection involved in all Event accesses. Whether that cost is affordable depends on the application, but it has a â€œbad smellâ€ (in the Extreme Programming sense). The purpose of an Event is to allow callbacks to be attached and thereâ€™s nothing about this that suggests Events should be stored on the heap.</p>
<h2>Asking the Wrong Question?</h2>
<p>In my experience, if a neat and tidy solution seems elusive itâ€™s usually because weâ€™re trying to solve the wrong problem. So, letâ€™s look at the problem again and try to understand it better.</p>
<p>What is it about the Event classes that makes them so uncooperative? It is simply that an Event copies its callbacks when the Event itself is copied. It does so because it owns the callbacks. Does it need to own its callbacks? Well, no, it doesnâ€™t, so letâ€™s see what happens if we remove the responsibility for creating and destroying callbacks from the Event classes.</p>
<p>Firstly, the Event classes become a lot simpler - little more than a list of pointers to abstract functions. Listing 4 shows a reasonable implementation of the simpler Event. Note that the <code>std:</code>: prefix has been omitted (and an unnecessary <code>typedef</code> introduced) to simplify the layout of the code on the printed page.</p>

<table class="sidebartable">
<tr>
<td>
<pre class="programlisting">// Abstract Function interface class.

template&lt;typename Arg&gt;
struct AbstractFunction
{
    virtual ~AbstractFunction() {}
    virtual void operator() (Arg) = 0;
};

// Event class template.

template&lt;typename Arg&gt;
struct Event : list&lt;AbstractFunction&lt;Arg&gt;*&gt;
{
    void notify(Arg arg)
    {
        typedef AbstractFunction&lt;Arg&gt; Func;
        for_each(
            begin(), end(),
            bind2nd(mem_fun( &amp;Func::operator()), arg));
    }
};

</pre>
</td>
</tr>
<tr>
<td class="title">Listing 4 - Revised Event class template.</td>
</tr>
</table>

<p>In this version of the Event classes I have omitted the <code>attach()</code> and <code>detach()</code>functions because I feel the std::list member functions already do an adequate job. In fact, the full splendour of the <code>std::list</code> interface has been made available to clients of the Event classes by using public inheritance.</p>
<h2>Making Connections</h2>
<p>Having removed the responsibility for creating and destroying callbacks from the Event classes, we can either invent something else for that purpose or pass the buck to the client code. I propose to offer the programmer a choice. The new Event/Callback library will provide a Connection class template that manages callbacks itself; alternatively, the client code can create and destroy its own callbacks. Sometimes we can have our cake and eat it!</p>
<p>Listing 5 shows the Connection template and the Callback template used in its implementation.</p>

<table class="sidebartable">
<tr>
<td>
<pre class="programlisting">// Callback class template.

template&lt;typename Arg, typename Function&gt;
class Callback : public AbstractFunction&lt;Arg&gt;
{
public:
    Callback(Function fn) : function(fn) {}

private:
    virtual void operator() (Arg arg)
    {
        function(arg);
    }

    Function function;
};

// Event/Callback connection.

template&lt;typename Arg&gt;
class Connection
{
public:
    template&lt;typename Fn&gt;
    Connection(Event&lt;Arg&gt;&amp; ev, Fn fn)
    : event(ev), callback(ev.insert(ev.end(), new Callback&lt;Arg,Fn&gt;(fn))
    {}

    ~Connection()
    {
        delete (*callback);
        event.erase(callback);
    }

private:
    Event&lt;Arg&gt;&amp; event; Event&lt;Arg&gt;::iterator callback;
};

</pre>
</td>
</tr>
<tr>
<td class="title">Listing 5 - The Callback and Connection templates.</td>
</tr>
</table>

<p>The Connection classes are designed for the â€œResource Acquisition Is Initialisationâ€ technique described in [1]. A callback is created and attached in the Connectionâ€™s constructor and (predictably) the callback is detached and destroyed in the Connectionâ€™s destructor. Instead of calling <code>attach()</code>and <code>detach()</code> the client program creates and destroys a Connection object.</p>
<h2>Copying Connections</h2>
<p>The Connection classes as shown here suffer from the same disease as the old Event classes - they can not be copied safely. However, an event with two connections to the same callback would invoke the callback twice each time the event occurs and itâ€™s difficult to see what use that might be. It is tempting, therefore, to make the Connection classes non-copyable (by deriving them from the <code>boost::noncopyable</code> class, for example). On the other hand, it might very well be useful to store Connections in standard containers, and for that they must be copyable.</p>
<p>One way to make Connections copyable is to have them store a shared-pointer to a reference-counted callback and provide appropriate copy constructor and copy assignment functions.<sup><a id="fnref:1" href="#fn:1" rel="footnote">1</a></sup> Doing so opens up the possibility of iterators being invalidated, but this is no longer a problem for the Event/Callback library. It was a problem in the old library because it required the client code to store the iterator returned by <code>attach()</code> and supply it to the <code>detach()</code> function. There is no such requirement for Connections.</p>
<h2>Object Lifetimes</h2>
<p>Typically, a callback will invoke a member function. It is important, therefore, for the callbackâ€™s target object to exist when the callback executes. Similarly, an Event must continue to exist until all its Connections have been destroyed because the Connectionâ€™s destructor will erase a pointer from the Event. I <strong>think</strong> these restrictions are best treated as requirements imposed on the client code by the library. An alternative approach is to maintain enough information within the library to handle these situations internally. The Boost.Signals library [2] and the SigC++ library<sup><a id="fnref:2" href="#fn:2" rel="footnote">2</a></sup> seem to offer this type of full lifetime management.</p>
<h2>Sample Code</h2>
<p>Listing 6 illustrates how the new version of the Event/Callback library is used. It shows a snippet from the sample program given in Part 1 of this article, slightly modified to show an explicit <code>detach()</code> call and to fit into a two-column page layout. The code in the left column uses the original version of the library in which callbacks are owned by the Event; the right column shows the new version in which the callbacks are owned by a Connection object. The difference is minimal. Where the old code had an <code>attach()</code> call, the new code creates a Connection object; and where the old code had an explicit <code>detach()</code>, the new code uses the implicit destruction of the Connection object. In this simple program the benefit of the new design is not very striking, but it should make the Logic Gates program a whole lot easier to write (if we ever find the time to implement it).</p>

<table class="sidebartable">
<tr>
<td width="50%">
<pre class="programlisting">// Old Event/Callback example

#include &lt;iostream&gt;
#include &quot;Event.hpp&quot;

using namespace std;
...

// A callback function.
void print(Button::State state)
{
    cout &lt;&lt; &quot;New state = &quot;
         &lt;&lt; state
         &lt;&lt; endl;
}

// A sample program
int main()
{
    Button button;
    cout &lt;&lt; &quot;Initial state = &quot;
         &lt;&lt; button.state
         &lt;&lt; endl;

    Event&lt;Button::State&gt;::iterator i =
        button.stateChanged.attach(
            print
        );

    button.press();
    button.release();
    button.stateChanged.detach(i);

    return 0;
}</pre>
</td>
<td>
<pre class="programlisting">// New Event/Callback example

#include &lt;iostream&gt;
#include &quot;Event.hpp&quot;

using namespace std;
...

// A callback function.
void print(Button::State state)
{
    cout &lt;&lt; &quot;New state = &quot;
         &lt;&lt; state
         &lt;&lt; endl;
}

// A sample program
int main()
{
    Button button;
    cout &lt;&lt; &quot;Initial state = &quot;
         &lt;&lt; button.state
         &lt;&lt; endl;

    Connection&lt;Button::State&gt;
    connection(
        button.stateChanged,
        print
    );

    button.press();
    button.release();

    return 0;
}
</pre>
</td>
</tr>
<tr>
<td colspan="2" class="title">Listing 6 - Sample program.</td>
</tr>
</table>

<h2>Roll-Your-Own Connections</h2>
<p>The Connection classes create callbacks on the heap. In cases where callbacks are better stored as local objects or as part of larger objects the programmer can use the Callback template directly. Listing 7 shows an example in which an Observer is its own callback.</p>

<table class="sidebartable">
<tr>
<td>
<pre class="programlisting">// Callback as part of an Observer

class Observer : public
    AbstractFunction&lt;Button::State&gt;
{
public:
    Observer(Event&lt;Button::State&gt;&amp; e)
    : event(e)
    {
        callback = event.insert(event.end(), this);
    }

    ~Observer()
    {
        event.erase(callback);
    }

private:
    virtual void operator() (Button::State state)
    {
        cout &lt;&lt; &quot;Button state = &quot; &lt;&lt; state &lt;&lt; endl;
    }

    Event&lt;Button::State&gt;&amp; event;
    Event&lt;Button::State&gt;::iterator callback;
};

</pre>
</td>
</tr>
<tr>
<td class="title">Listing 7 - Callback as part of an Observer</td>
</tr>
</table>
<p></p>

<h2>Conclusion</h2>
<p>The Event/Callback library described in part 1 of this article seemed to serve its purpose well. Experience has shown, however, that there are circumstances where it doesnâ€™t live up to its promise. This is called â€œlearningâ€ and I believe it illustrates once again that software development is a young technology.</p>
<p>More experience is needed with the new Event/Callback library before we can be confident that it, too, is not flawed, but Iâ€™m fairly confident that the new is better than the old.</p>
<p>Phil Bass<br>
phil@stoneymanor.demon.co.uk</p>
<h2>References</h2>
<p>1 Bjarne Stroustrup, The C++ Programming Language, Addison Wesley, ISBN 0-201-889554-4.<br>
2 See http://www.boost.org/</p>

<div class="footnotes">
<hr>
<ol>
<li id="fn:1">
<p>Writing a copyable Connection class is left as an exercise for the reader.&nbsp;<a href="#fnref:1" rev="footnote">â†©</a></p>
</li>
<li id="fn:2">
<p>Sorry, I donâ€™t have a reference to hand for the SigC++ library.&nbsp;<a href="#fnref:2" rev="footnote">â†©</a>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
