    <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  :: The uses and abuses of inheritence</title>
        <link>https://members.accu.org/index.php/articles/1450</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>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #17/18 - Jan 1997</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/articles/">All</a>

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

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

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

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

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

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c228/">1718</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-228/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+228/">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;The uses and abuses of inheritence</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 31 January 1997 08:59:00 +00:00 or Fri, 31 January 1997 08:59:00 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<p>
C++ programmers come across inheritance at&nbsp; an early stage in
their acquisition of programming knowledge. However I have long had an
itch in this area based on the feeling that too often what they are
taught as well as what they acquire from reading and following examples
is not exactly the way it should be done. In this article I want to
explore my thoughts on the subject and I hope that you will all read
them critically. In other words, I will be profoundly unhappy if Sean
gets no response.
</p>
<p>There are three prime reasons (that I know of)&nbsp; for using
inheritance:</p>
<ul>
  <li>To reuse an existing class with modifications.</li>
  <li>To provide an extension, to an existing class by adding
functionality usually with extra data.</li>
  <li>To support polymorphic types.</li>
</ul>
<p>To keep the amount of code under control&nbsp; most of my examples
will contain just enough to support the text.</p>
<h2>Inheritance for reuse</h2>
<p>Though many books avoid making this explicit, most of them provide
examples of inheritance that are exactly this. Consider:</p>
<pre>class Miss {&nbsp; <br>public:<br>  // standard constructors etc.<br>  float do_something ();<br>  float do_ok();<br>};<br></pre>
<p>Assume that this class almost provides a solution to my client's
problem but I must have&nbsp; <span style="font-family: monospace;">do_something()</span>
return a <span style="font-family: monospace;">double</span>. Being an
ethical programmer I avoid the cop-out of redefining the problem to
align it with the available solution. However I do not want to have to
rewrite (or even simply clone and modify) the class in its entirety. We
all know what happens if you touch existing code. If left to the
information provided by most books, inexperienced programmers come up
with:</p>
<pre>class Poor_Solution: public Miss {&nbsp; <br>public:<br>&nbsp; double do_something();<br>};<br></pre>
<p>I think this is a mistake. <span style="font-family: monospace;">Poor_Solution</span>&nbsp;
instances may share much behaviour with <span
 style="font-family: monospace;">Miss</span> ones but they break the
substitution rule, they behave differently in at least one instance. We
must look again at our concepts. Our use of <span
 style="font-family: monospace;">Miss</span> to provide <span
 style="font-family: monospace;">Solution</span> is an implementation
shortcut. Implementation details should be <span
 style="font-family: monospace;">private</span>, or at the very least <span
 style="font-family: monospace;">protected</span>. We have two
mechanisms available to represent this relationship:</p>
<pre>class Solution: Miss { // private inheritance<br>  // interfaces<br>};<br></pre>
<p>or</p>
<pre>class Solution {<br>  Miss s;&nbsp;&nbsp; // layering or aggregation&nbsp; <br>  // interfaces<br>};<br></pre>
<p>I have difficulty with distinguishing these choices and I would
welcome someone writing an article on the advantages and disadvantages
of each. The differences seem subtle and I suspect that each
method has its uses.</p>
<p>In both cases the programmer now has to provide a complete
public interface rather than rely on inheritance. This is a very small
cost. Each member function that you wish to import from the Miss
interface must be provided by an inline wrapper. For example:</p>
<pre>float do_ok() { return s.do_ok(); }</pre>
<p>The advantage that you get is that instances of&nbsp; Solution
cannot accidentally be passed to functions that want a reference or
pointer to a Miss object. If you doubt that this could matter, then
remember that such functions rely on Miss behaviour and what you have
given them is an object that is intended to have an alternate
behaviour. In my example the difference is miniscule but in real
code the changed behaviour is likely to be more substantial.</p>
<p>I suggest that the coding rule should be:</p>
<p style="font-style: italic; margin-left: 40px;">If you want a variant
of an existing type that&nbsp; has
different behaviour then use either private inheritance or layering. Do
not use public inheritance.</p>
<p style="font-style: italic;">Just to show how different languages
have different
philosophies, Smalltalk books advocate inheritance for reuse. But
support for inheritance is rather different between the two
languages.&nbsp; - Ed.</p>
<h2>Inheritance for enhancement</h2>
<p>At first sight this is the same as 'Inheritance for&nbsp;
Reuse' but a second glance reveals that this is not the case. Consider
the relationship between <span style="font-family: monospace;">istream
</span>and <span style="font-family: monospace;">ifstream</span>. An <span
 style="font-family: monospace;">ifstream </span>instance
should be able to substitute as an <span
 style="font-family: monospace;">istream </span>one. In other words it
should present the whole of the <span style="font-family: monospace;">istream
</span>interface plus, possibly,
some extra elements. Note that I am writing about interfaces, not
implementation. Of course some aspects of the <span
 style="font-family: monospace;">istream </span>interface
may be implemented differently for an <span
 style="font-family: monospace;">ifstream </span>one.</p>
<p>These potential differences are clearly identified in
the base class because they have been declared <span
 style="font-family: monospace;">virtual</span>. The only places
that you should over-ride a public base class implementation is
where the functions are <span style="font-family: monospace;">virtual </span>ones.
This ensures that all functions
that take references or pointers as parameters will behave
correctly when supplied a derived type argument.</p>
<p>If you want to over-ride non-virtual functions&nbsp; in a
class that you do not own, you must go through two stages. First use
<span style="font-family: monospace;">private </span>inheritance to
create a new base class with the
appropriate <span style="font-family: monospace;">virtual </span>qualified
functions then derive from that.</p>
<p>Another feature of this situation is that you should consider some
form of smart pointer to handle dynamic instances of these classes. If
you neglect this and use ordinary pointers you will find that your code
is not exception safe. In other words you will be leaking resources
when exceptions are thrown over dynamic instances.</p>
<p>If exceptions are your only concern you can&nbsp; make do with
a pretty simple smart pointer but if you want to use containers of
mixtures of base and derived instances you will need to provide a
smarter pointer. If you want to use STL containers and algorithms where
exceptions may occur you should know that some combinations of STL
containers and algorithms are unsafe in the presence of an exceptions.</p>
<p>Clearly there are good uses for 'inheritance for&nbsp;
enhancement', it is one of the pillars underpinning the <span
 style="font-family: monospace;">iostream </span>part
of the Standard C++ library, however inexperienced programmers should
stick to the principle 'only change what the original (base class)
designer anticipated changing'.</p>
<p>I could write much more but this is not intended to be the
main focus of this article, not least because it is one of the hardest
aspects of inheritance to get right.</p>
<p style="font-style: italic; font-weight: bold;">Do not over-ride
non-virtual member functions&nbsp; of a
public base class.</p>
<h2>Inheritance for pure polymorphism</h2>
<p>Fundamentally the concept of polymorphism is one of providing
multiple implementations for a single interface. The implementation
will be chosen in the runtime context, so called late or dynamic
binding.</p>
<p>When I use the term 'pure polymorphism' I am&nbsp; referring
to a type where all instances have identical interfaces even if the
implementation (and therefore the detailed behaviour) may be different.
Such objects are characterised by a complete set of virtual functions
for the polymorphic behaviour coupled with any suitable functions to
supply invariant behaviour. Derived classes will only provide
constructors, destructor, member data and over-rides (implementations)
of virtual base functions. There will be no extra public member
functions and public static members. In other words, the public
interface of all derived classes must be exactly that of the base class.</p>
<p>You may recognise this as the kind of situation where you
provide an Abstract Base Class. True, but that is an implementation
technique which should be hidden from the user. Good coding depends on
abstraction and encapsulation to hide complexity. Expecting the
application programmer to use pointers (smart or otherwise) to manage
concrete instances of a pure polymorphic type is leaving your job half
done. The user of your polymorphic type should not need to know of the
mechanisms. For example, the user of a Shape abstraction should be able
to create and use Shape objects based entirely on the public interface
of a Shape. Yes, read that again and realise that an ABC cannot meet
that expectation because there are no objects of an ABC type. I want to
spend the remainder of this article introducing you to a simple method
that will provide instances of a polymorphic type so that you can clone
them, copy assign them, have containers of them etc.</p>
<p>&nbsp;Though it may not be the most perfect of designs, I am going
to use International postal addresses as my example because it is
something we all understand and I can provide a very simple set of
interfaces.</p>
<p>Let me start by writing the interface I want, and&nbsp; then
see if there is some way I can achieve it.</p>
<pre>class Address { <br>// the works&nbsp; <br>public:<br>  Address ();&nbsp; // default constructor<br>               // for containers <br>  Address (String country,<br>           iostream init_data = cin);&nbsp; <br>  Address (const Address&amp;);&nbsp; // clone a<br>                             // specific address&nbsp; <br>  ~Address ();<br>  Address &amp; operator = (const Address &amp;);&nbsp; const<br>  Address &amp; printon (ostream &amp; out = cout) const;&nbsp; <br>  Address &amp; readfrom (istream &amp; in = cin);<br>};<br><br></pre>
<p>The real crunch issue is copying. Different&nbsp; countries will
have different amounts of data. Worse, copy assignment will not be of
use unless we can manage copying between addresses of different
types. Let us back up a little and create an abstract base class:</p>
<pre>class Address_Data { <br>  // suppress cloning<br>  Address_Data (const Address_Data &amp;);&nbsp; <br>  Address_Data &amp; operator = (const<br>          Address_Data &amp;); // and copying&nbsp; <br>public:<br>  Address_Data ();&nbsp; virtual ~Address_Data (){} <br>  virtual const Address_Data &amp; <br>           printon (ostream &amp; out = cout) const = 0;</pre>
<pre>  virtual Address_Data &amp; <br>           readfrom (istream &amp; in = cin) =0;<br>};<br></pre>
<p>Note that I have had to remove the copying&nbsp; functionality
because you cannot copy an abstraction. I have also removed the
second constructor because it does not have any meaning in
context. However what I really need is some form of 'virtual
constructor' so that I can construct the correct type of address
when I know what it is. As I cannot have virtual constructors I had
better declare a couple of functions to do the work:</p>
<pre>virtual Address_Data*<br>              clone_address_data() = 0;&nbsp; <br>Address_Data * make_address_data<br>                     (const String &amp; country,<br>                      iostream &amp; data = cin);</pre>
<p>The first of these will be a pretty straightforward. The second will
be a hack, anyone with a better solution should write it up and send it
in. For the first, each concrete class derived from<span
 style="font-family: monospace;"> Address_Data</span>, for example <span
 style="font-family: monospace;">UK_Address_Data</span> will provide:</p>
<pre>Address_Data * clone_address_data()<br>      {return new UK_Address_Data (*this);<br>}<br></pre>
<p>These relies on each concrete class having a copy constructor
available.</p>
<p>Next, every concrete class derived from <span
 style="font-family: monospace;">Address_Data</span>, will
include a constructor of the form:</p>
<pre>UK_Address_Data(iostream in = cin) {<br>&nbsp; readfrom(in);<br>}<br></pre>
<p>Then&nbsp; we&nbsp; can&nbsp;
implement <span style="font-family: monospace;">make_address_data()</span>
with:</p>
<pre>Address_Data *<br>  make_address_data(const String &amp; country,<br>                    iostream &amp; data){&nbsp; <br>    if (!strcmp(country, &quot;UK&quot;))<br>      return new <br>        UK_Address_Data(data);&nbsp; <br>    if (!strcmp(country, &quot;USA&quot;))<br>      return new <br>        USA_Address_Data(data); <br>    // etc., one per possible country&nbsp; <br>    return 0;&nbsp; // default to null pointer<br>}<br></pre>
<p>Note that this function will be a static&nbsp; member function
of <span style="font-family: monospace;">Address_Data</span> because
it is called to make concrete instances of
addresses. It will also need to be changed when new concrete classes
are added so the implementation code needs to be separate from any
other code so that it can be updated independently.</p>
<p>As you will see shortly, I do not need to pro vide a copy
assignment for the concrete classes.</p>
<p>Now let me look at a typical complete concrete&nbsp; class.</p>
<pre>class UK_Address_Data: <br>                 public Address_Data <br>{<br>  friend class Address_Data; <br>  // provide<br>  // access for the abstraction&nbsp; <br>  // provide for appropriate data <br>  UK_Address_Data(const UK_Address_Data &amp;);<br>  // to be implemented&nbsp; <br>  UK_Address_Data &amp; operator = (<br>               const UK_Address_Data &amp;);&nbsp; <br>  // suppress copying<br>  UK_Address_Data (iostream &amp; in = cin)<br>  { readfrom(in); };&nbsp; <br>  ~UK_Address_Data (){<br>  //delete data if necessary <br>  ) <br>  const Address &amp; printon(ostream &amp; out = cout) const;&nbsp; <br>  Address &amp; readfrom (istream &amp; in = cin);<br>  Address_Data * clone_address_data()<br>};<br></pre>
<p>Now go back to <span style="font-family: monospace;">Address_Data</span>
and remove&nbsp; <span style="font-family: monospace;">public </span>so
that
the ABC is entirely <span style="font-family: monospace;">private </span>as
will be all its derived concrete
classes. In other words nothing can get at any part of the&nbsp;
implementation. We now have to provide a channel by which exactly one
thing can get at this hierarchy. In <span
 style="font-family: monospace;">Address_Data</span> we declare <span
 style="font-family: monospace;">Address </span>a
<span style="font-family: monospace;">friend</span>. By the way, I
believe that the uses of <span style="font-family: monospace;">friend </span>in
this example
are exactly what friendship is all about. It is to support
implementation hiding, not to expose data just because it is convenient
for lazy or incompetent programmers.&nbsp;
</p>
<p>Now let me go back to the original class and&nbsp; see how I
can use my ABC rooted hierarchy to solve my problem.</p>
<pre>class Address {<br>  Address_Data * the_works;&nbsp; <br>public:<br>  Address (): the_works(0) {} // default<br>  // constructor for containers&nbsp; <br>  Address (String country,<br>           iostream init_data =cin )&nbsp; :<br>    the_works(make_address_data(country,<br>                                init_data)) {}&nbsp; <br><br>  Address (const Address &amp;. a) :
    the_works(a.clone_address_data()){} <br><br>  ~Address ()<br>  { delete the_works, the_works=0; }&nbsp; <br><br>  Address &amp; operator=(const Address &amp; a) <br>  { Address * temp =<br>             a.clone_address_data(); <br>    delete the_works, the_works = temp;&nbsp; <br>    return * this ; <br>  ) <br><br>  const Address &amp; printon (ostream &amp; out = cout) const <br>  {&nbsp; the_works -&gt; printon(out); <br>     return *this;<br>  }<br></pre>
<pre>&nbsp; Address &amp; readfrom {<br>                istream &amp; in = cin) {<br>    the_works-&gt;readfrom(in); <br>    return *this;<br>  }<br>};<br></pre>
<p>Note that there is precisely one change to my&nbsp; original.
I have provided a single item of data through which I can access my
carefully honed extensible implementation. Oh, I have added the
implementation of the functions in class because they are simple enough
to be <span style="font-family: monospace;">in-line</span>. Do you
agree?</p>
<p>No doubt many of you can pick at the above code and
argue about the design. Good, you should not accept something just
because it is in print. However I think that the principle is right.
Some of you may have recognised <span style="font-family: monospace;">Address
</span>as being a surrogate class. If
you did not and have wondered what the term means, now you know.</p>
<p>&nbsp;Anytime you find yourself handling dynamic instances of a
polymorphic type with pointers I&nbsp; suggest you should step back and
consider if this is essential or just a feature of a poor design.
Indeed, anytime you find yourself using&nbsp; new and delete at the
application level you have cause to investigate. Currently so many
libraries are poorly designed so you may have to resort to such
complexity but...</p>
<p>&nbsp;I believe that the reason that C++ appears to&nbsp; have such
a steep learning curve is that too many tools are half finished. This
is compounded by the old hands continuing to use idioms that they
have imported from C without realising that there are better
alternatives in C++. You can use C++ as if it was C, use overt arrays
of pointers etc. but you do not have to.</p>
<p>&nbsp;I have deliberately left one member function&nbsp; of the
Address and Address_Data hierarchy poorly designed and
implemented. There is a copy of 'Ruminations on C++' waiting for
the person who provides the best correction to this fault. Of
course, first you must identify it.<br>
</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
