    <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  :: Programming with Interfaces in C++</title>
        <link>https://members.accu.org/index.php/journals/400</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 #49 - Jun 2002 + 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/c196/">49</a>
                    (8)
<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/c196-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c196+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;Programming with Interfaces in C++</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 June 2002 17:46:10 +01:00 or Wed, 26 June 2002 17:46:10 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id="d0e18"></a></h2>
</div>
<p>In a previous issue of Overload [<a href=
"#Goldthwaite">Goldthwaite</a>], Lois Goldthwaite gave an
illuminating explanation of compile time polymorphism using
templates.</p>
<p>This has the advantage over run time polymorphism that it does
not require classes to be derived from a common base class to share
an interface, and that it does not incur the cost of a virtual
function table.</p>
<p>It is usually pointed out that it suffers the disadvantage that
objects of different types with the same interface cannot be held
in a type safe container, since such containers do require
contained objects to share a common type.</p>
<p>However we can in fact get the best of both worlds since it is
possible to convert objects that share compile time polymorphism
into objects that share run time polymorphism. I infer from Kevlin
Henney's article in Overload 48 [<a href="#Henney">Henney</a>] that
the technique I describe uses the External Polymorphism
pattern.</p>
<p>First, a recapitulation of Lois' classes:</p>
<pre class="programlisting">
// talkers.h (include guards not shown)
#include &lt;iostream&gt;

class Dog {
public:
  void talk() const {
    std::cout &lt;&lt; &quot;woof woof&quot;
              &lt;&lt; std::endl;
  }
};

class CuckooClock {
public:
  void talk() const {
    std::cout &lt;&lt; &quot;cuckoo cuckoo&quot;
              &lt;&lt; std::endl;
  }
};

class BigBenClock {
public:
  void talk() const {
    std::cout
        &lt;&lt; &quot;take a long tea-break&quot;
        &lt;&lt; std::endl;
  }
  void playBongs() const {
    std::cout &lt;&lt; &quot;bing bong bing bong&quot;
              &lt;&lt; std::endl;
  }
};

class SilentClock {
};
</pre>
<p>We can provide compile time polymorphism by means of a function
template, which can be specialised to adapt functionality (in the
case of <tt class="classname">BigBenClock</tt>) and to supply
missing functionality (in the case of <tt class=
"classname">SilentClock</tt>):</p>
<pre class="programlisting">
// talkative_generic.h
// (include guards not shown)

class BigBenClock;
class SilentClock;

template&lt; class T &gt;
void talkativeGenericTalk(const T&amp; t) {
  t.talk();
}

template&lt;&gt;
void talkativeGenericTalk(const
             BigBenClock&amp; bigBenClock);

template&lt;&gt;
void talkativeGenericTalk(const
             SilentClock&amp; silentClock);

// talkative_generic.cpp
#include &quot;talkative_generic.h&quot;
#include &quot;talkers.h&quot;
#include &lt;iostream&gt;
template&lt;&gt;
void talkativeGenericTalk(const
             BigBenClock&amp; bigBenClock) {
             bigBenClock.playBongs();
}

template&lt;&gt;
void talkativeGenericTalk(const
             SilentClock&amp; silentClock) {
  std::cout &lt;&lt; &quot;tick tock&quot;
            &lt;&lt; std::endl;
}
</pre>
<p>The equivalent interface in run time polymorphism can be defined
as:</p>
<pre class="programlisting">
// talkative_interface.h
// (include guards not shown)
class TalkativeInterface {
public:
  virtual TalkativeInterface*
                         clone() const = 0;
  virtual void talk() const = 0;
  virtual ~TalkativeInterface(){}
};
</pre>
<p>We then need a mechanism for converting objects with the compile
time interface to this type. We can do this by means of a factory
class:</p>
<pre class="programlisting">
// talkative_interface_factory.h
// (include guards not shown)
#include &quot;talkative_interface.h&quot;
#include &quot;talkative_generic.h&quot;

class TalkativeInterfaceFactory {
public:
// Callers should take ownership of the
// pointers returned by the public functions

  template&lt; class T &gt;
  static TalkativeInterface* convert(T* t) {
    return new TalkativeImplementation&lt;T&gt;(t);
  }

  template&lt; class T &gt;
  static TalkativeInterface*
                   copy(const T&amp; t) {
    return new TalkativeImplementation&lt;T&gt;(t);
  }

private:
  TalkativeInterfaceFactory();
  TalkativeInterfaceFactory(const
                TalkativeInterfaceFactory&amp;);
  TalkativeInterfaceFactory&amp; operator=(
          const TalkativeInterfaceFactory&amp;);
  ~TalkativeInterfaceFactory();

  template&lt; class T &gt;
  class TalkativeImplementation
             : public TalkativeInterface {
    public:
      TalkativeImplementation(T* t)
             : t_(t), owner_(false) {}
      TalkativeImplementation(const T&amp; t)
             : t_(new T(t)), owner_(true) {}
      virtual TalkativeInterface*
                         clone() const {
        return new
            TalkativeImplementation&lt;T&gt;(*t_);
      }

      virtual void talk() const {
        talkativeGenericTalk(*t_);
      }

      virtual ~TalkativeImplementation() {
        if(owner_) delete t_;
      }
    private:
      TalkativeImplementation(const
                  TalkativeImplementation&amp;);
      TalkativeImplementation&amp; operator=(
                  const TalkativeImplementation&amp;);
      T* t_;
      bool owner_;
  };
};
</pre>
<p>The key to the factory class is the nested adapter class
template <tt class="classname">TalkativeImplementation</tt> in the
private part. This is derived from <tt class=
"classname">TalkativeInterface</tt> to give it the required type.
It is a template so that it can be instantiated with any class
<tt class="type">T</tt> that supports the compile time
polymorphism; the required member function <tt class=
"methodname">talk()</tt> is implemented by using the function
template <tt class="function">talkativeGenericTalk()</tt>.</p>
<p>The factory provides two static public functions <tt class=
"methodname">convert()</tt> and <tt class="methodname">copy()</tt>
which use the <tt class="classname">TemplateImplementation</tt>
class template to perform the conversion (in the former by sharing
an existing pointer, in the latter by creating a new, independent
one).</p>
<p>For the sake of clarity I have used raw pointers throughout the
code. In practice I would use a reference counting smart pointer
everywhere there is a raw pointer. This would avoid the need for
the <tt class="varname">owner_</tt> member variable and make the
destructor of <tt class="classname">TalkativeImplementation</tt>
trivial. For a full discussion of smart pointers see Alexandrescu
[<a href="#Alexandrescu">Alexandrescu</a>]).</p>
<p>Here is some test code to show the use of the factory to build a
vector of talkative objects using <tt class=
"methodname">copy()</tt>:</p>
<pre class="programlisting">
// test_talkative.cpp

#include &quot;talkers.h&quot;
#include &quot;talkative_interface_factory.h&quot;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

namespace
{
  typedef std::vector&lt;TalkativeInterface*&gt;
      Talkers;
  struct Talk {
    void operator()(const
             TalkativeInterface* talker) {
      talker-&gt;talk();
    }
  };

  template&lt; class T &gt;
  struct Destroy {
    void operator()(const T* t) {
      delete t;
    }
  };
}

int main(int, char**)
{
  Dog aDog;
  CuckooClock aCuckooClock;
  BigBenClock aBigBenClock;
  SilentClock aSilentClock;
  Talkers talkers;
  talkers.push_back(
    TalkativeInterfaceFactory::copy(aDog));

  talkers.push_back(
    TalkativeInterfaceFactory::copy(
      aCuckooClock));

  talkers.push_back(
    TalkativeInterfaceFactory::copy(
      aBigBenClock));

  talkers.push_back(
    TalkativeInterfaceFactory::copy(
      aSilentClock));

  std::for_each(talkers.begin(),
                talkers.end(), Talk());
  
  std::for_each(talkers.begin(),
                talkers.end(),

  Destroy&lt;TalkativeInterface&gt;());

  return 0;
}
</pre>
<p>This produces the output:</p>
<pre class="programlisting">
woof woof
cuckoo cuckoo
bing bong bing bong
tick tock
</pre>
<p>One practical application of this factory class would be to
implement the Observer pattern [<a href="#GoF">GoF</a>]. In fact,
it was Pete Goodliffe's series of articles on that subject
[<a href="#Goodliffe">Goodliffe</a>] that set me thinking about
this in the first place. In this pattern, a Subject maintains a
list of Observers. With this factory class we would be able to
convert a variety of Observers, not necessarily sharing a common
base class, so that they could be added to such a list. The
<tt class="methodname">convert()</tt> operation would be used in
this case. The following test code demonstrates the effect achieved
by using <tt class="methodname">convert()</tt> rather than
<tt class="methodname">copy()</tt>:</p>
<pre class="programlisting">
// guard_dog.h (include guards not shown)

#include &quot;talkers.h&quot;
#include &lt;iostream&gt;

class GuardDog: public Dog {
public:
  GuardDog() : barkLoudly(false) {}
  GuardDog&amp; deterIntruder() {
    barkLoudly = true; return *this;
  }

  void talk() const {
    if(barkLoudly) {
      std::cout &lt;&lt; &quot;WOOF WOOF&quot; &lt;&lt; std::endl;
    }
    else {
      Dog::talk();
    }
  }

private:
  bool barkLoudly;
};

// test_talkative.cpp

// other includes as before

#include &quot;guard_dog.h&quot;

// typedef Talkers, classes Talk and
// Destroy as before
int main(int, char**) {

  GuardDog* aGuardDog = new GuardDog();

  Talkers talkers;

  talkers.push_back(
        TalkativeInterfaceFactory::convert(
                                 aGuardDog));

  std::for_each(talkers.begin(),
                talkers.end(), Talk());

  aGuardDog-&gt;deterIntruder();

  std::for_each(talkers.begin(),
                talkers.end(), Talk());

  std::for_each(talkers.begin(),
                talkers.end(),
                Destroy&lt;TalkativeInterface&gt;());

  delete aGuardDog;

  return 0;
}
</pre>
<p>This produces the output:</p>
<pre class="programlisting">
woof woof
WOOF WOOF
</pre>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e129" id="d0e129"></a>References:</h2>
</div>
<div class="bibliomixed"><a name="Goldthwaite" id=
"Goldthwaite"></a>
<p class="bibliomixed">[Goldthwaite] Lois Goldthwaite, &quot;Programming
With Interfaces In C++: A New Approach&quot;, <span class=
"citetitle"><i class="citetitle">Overload 40</i></span>, December
2000</p>
</div>
<div class="bibliomixed"><a name="Henney" id="Henney"></a>
<p class="bibliomixed">[Henney] Kevlin Henney, &quot;Function Follows
Form&quot;, <span class="citetitle"><i class="citetitle">Overload
48</i></span>, April 2002</p>
</div>
<div class="bibliomixed"><a name="Alexandrescu" id=
"Alexandrescu"></a>
<p class="bibliomixed">[Alexandrescu] Andrei Alexandrescu,
<span class="citetitle"><i class="citetitle">Modern C++
Design</i></span>, Addison Wesley C++ In Depth Series, 2001</p>
</div>
<div class="bibliomixed"><a name="GoF" id="GoF"></a>
<p class="bibliomixed">[GoF] Erich Gamma, Richard Helm, Ralph
Johnson and John Vlissides, <span class="citetitle"><i class=
"citetitle">Design Patterns: Elements of Reusable Object-Oriented
Software</i></span>, Addison Wesley, 1995</p>
</div>
<div class="bibliomixed"><a name="Goodliffe" id="Goodliffe"></a>
<p class="bibliomixed">[Goodliffe] Pete Goodliffe, &quot;Experiences of
Implementing the Observer Design Pattern Parts 1-3&quot;, <span class=
"citetitle"><i class="citetitle">Overload 37</i></span>, May 2000,
<span class="citetitle"><i class="citetitle">Overload
38</i></span>, August 2000, <span class="citetitle"><i class=
"citetitle">Overload 41</i></span>, February 2001</p>
</div>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
