    <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  :: Class Struggle</title>
        <link>https://members.accu.org/index.php/articles/1388</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">Design of applications and programs + Overload Journal #3 - Aug 1993</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/c67/">Design</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/c225/">03</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c67+225/">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;Class Struggle</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 01 August 1993 11:53:00 +01:00 or Sun, 01 August 1993 11:53:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<p>In the previous two editions of Overload, we have looked at
encapsulation and overloading of operators. In this tutorial I will
look at inheritance and polymorphism, taking one of the most common
examples, a graphics class to pieces and show you that bitmaps and line
drawings can be manipulated as easy as simple shapes.</p>
<p>Before I start to describe the mechanism of inheritance, I would
like to provide a word of warning. Inheritance is a powerful tool and,
like all tools must be used in the correct manner. Too much emphasis is
placed on inheritance by novice C++ programmers, who tend to want to
see their entire program as an inheritance tree, and often struggle to
achieve this.</p>
<p>The example source is full of holes, as I try not to be compiler
specific. It is your task this issue to fill in your compiler specific
bits and send them in to me. One of you will lucky and receive a C++
book for your troubles.</p>
<p>One of the most cited benefits of C++ is the degree of reusable code
that can be generated and indeed reused within the program. One of the
main reasons for this reuse is that C++ gives you the ability to build
and extend classes through inheritance. Each time you derive a child
class from its parent, you get all the functionality of the parent
without writing extra code. Classes can inherit from more than one
parent, this is called multiple inheritance, the child class inherits
data and behaviours from both its parents. For the moment we are going
to stick to single inheritance.</p>
<p>The parent class is called the base class, the child class is known
as the derived class. The base class is usually simpler than the
derived class, for the derived class contains everything in the base
class and, if it defines its own data or member functions, it is more
complex.</p>
<p>The terms used in the design tools for this is the gen-spec
relationship (generalisation-specialisation). The parent class is
general, the child class is a specialisation of its parent. Try
thinking of this in terms of everyday objects. Taking a car as being
our base class (the parent/generalisation) we can create more
specialised child classes such as sports cars, saloons and estate cars
derived from the parent. In the Rumbaugh Object Modelling Technique,
the symbol used for this gen-spec relationship is the triangle, the
point points towards the generalisation as in the following diagram.<br>
</p>
<p style="text-align: center;"><img alt="Gen-Spec diagram for Car class"
 src="/content/images/journals/ol03/Figure%201%20-%20Class%20Struggle.png"><br>
</p>
<p>So how does a class inherit its parents features. Taking the above
example, we can create the following class structure:</p>
<pre class="programlisting">class Car {};<br>class Sports_Car : public Car {};<br>class Saloon_Car : public Car {};<br>class LotusElan : public Sports_Car {};<br>class Mazda_MX5 : public Sports_Car {};<br>class Ford_Mondeo : public Saloon_Car;<br>class Vauxhall_Cavalier : public Saloon_Car{};</pre>
<p>The method of showing inheritance is the &quot;: public ...&quot;. You may
choose later to use private or protected inheritance, but not today.
OK, so now that we have inherited from our parents what can we do? You
have 2 choices, you can replace the features of your parent or you can
extend them. Extending your parents features is achieved in the normal
way by adding more member functions. Replacement can take the form of
restriction or modification and in order to be effective we need a
mechanism for replacing our parents member functions with our own ones.</p>
<p>This is achieved through a mechanism known as the virtual functions.
By using virtual functions you tell the compiler that it is not to link
the function until run-time as it may be replaced. This is known as
late-binding, the normal, C type compilations produce early-binding,
where the actual function to be called is known at link time.</p>
<p>Take the following example:</p>
<pre class="programlisting">class base<br>{<br>public:<br>  void write() {cout &lt;&lt; &quot;Hello I'm base&quot; &lt;&lt; endl;}<br>   void baseWrite() { write(); } <br>};<br><br>class derived : public base<br>{<br>public:<br>  void write() {cout &lt;&lt; &quot;Hello I'm derived&quot; &lt;&lt; endl;}<br>  void derivedWrite() { write(); } <br>};</pre>
<p>Creating an instance of base and calling baseWrite() will, as
expected produce the message declaring that it's the base. Creating an
instance of derived and calling derivedWrite() will produce a message
stating that it is the derived class and calling baseWrite will produce
the message that it is the base. In this case, because base has not
explicitly stated (by means of the virtual keyword) that the write
function can be replaced by any write functions belonging to its
children.</p>
<p>If we make the base::write() a virtual function, as follows:</p>
<pre class="programlisting">virtual void write() {cout &lt;&lt; &quot;Hello I'm base&quot; &lt;&lt; endl;}</pre>
<p>Now, the instance of base will behave the same as before, but when
calling either derivedWrite() or baseWrite() will produce a declaration
that it is the derived function being called.</p>
<p>The write() in the derived function is implicitly virtual even
though not specified with the virtual keyword, because its parents
member function by the same name and parameter list was virtual.</p>
<p>This method of replacing functions is known as polymorphism (many
forms) and is strictly a feature of member functions rather than
classes as a whole. Polymorphism does not apply to data; you cannot
make data virtual!</p>
<p>The extent to which we have seen this polymorphism used is not
particularly exciting so far. Its real power comes when you combine
this with pointers. We can have several classes derived from a common
base, and have a pointer (or array/list/collection of pointers) that
can now point to any of the derived types. Calling the common functions
in the base class will then go to the replaced function in the
appropriate class.</p>
<p>It's about time to start introducing the graphics classes promised
earlier to assist with the explanation. A collection of graphics shapes
can be manipulated without any regard to the actual shape, if they are
all derived from a common base class (called not surprisingly Shape).
By using the virtual mechanism to get the derived class to draw itself
whenever needed, the base class can quite happily manipulate everything.</p>
<p>The data held by the shape class is to include a centre, the colour,
the size and the velocity it moves in both the horizontal and vertical
directions.</p>
<pre class="programlisting">class shape<br>{<br>protected:<br>  int xc, yc;&nbsp;&nbsp; &nbsp;// x centre and y centre<br>  int lc;&nbsp;&nbsp; &nbsp;// line color<br>  int sz;&nbsp;&nbsp; &nbsp;// size<br>  int dx, dy;&nbsp;&nbsp; &nbsp;// direction for move in x and y planes <br>public:<br>  shape();<br>  void set(int x, int y, int s, int l);<br>  void set(int x, int y);<br>  void speed(int x, int y);<br>  void move(int new_x, int new_y);<br>  virtual void Draw() {}<br>  void travel();<br>};<br><br>//-------------------------------------<br>//&nbsp;&nbsp;&nbsp; S H A P E&nbsp;&nbsp; M E T H O D S<br>//-------------------------------------<br>shape::shape() : xc(0), yc(0), sz(10), lc(WHITE),dx(5),dy(5)<br>{ }<br><br>void shape::set(int x, int y, int s, int l)<br>{<br>  xc = x; yc = y; sz = s;<br>  lc = l; // set pen to colour lc<br>  draw();<br>}<br><br>void shape::set(int x, int y)<br>{<br>  xc = x; yc = y;<br>}<br><br>void shape::speed(int x, int y) <br>{<br>  dx = x;<br>  dy = y;<br>}<br><br>void shape::size(int x) <br>{<br>  // Set pen to background colour<br>  draw();<br>  sz=x;<br>  // set pen to colour lc<br>  draw(); <br>}<br><br>void shape::move(int new_x, int new_y)<br>{<br>  // Set pen to background colour <br>  draw();<br>  set(new_x,new_y); // Set pen to colour lc <br>  draw(); <br>}<br><br>void shape::travel() <br>{<br>  int x = xc + dx; int y = yc + dy;<br>  if (x&lt;0) {x = 0; dx = -dx;}<br>  if (y&lt;0) {y = 0; dy = -dy;}<br>  if (x&gt;getmaxx()) {x = getmaxx(); dx = -dx;}<br>  if (y&gt;getmaxy()) {y = getmaxy(); dy = -dy;}<br>  move(x,y); <br>}</pre>
<p>We now have a base class of shape, in order to be useful, we must
make more specific shapes. (Shape is too general). The only problem is,
what happens if the new derived doesn't replace the virtual draw
function. The solution to our problem lies in the ability to force the
new class to replace the virtual function. This simply involves
replacing the virtual draw function with what is called a pure virtual
function. virtual void Draw() = 0;</p>
<p>The '= 0' means that any class deriving from shape must replace the
draw member function. The shape class is now known as an abstract
class. It is incapable of being instantiated as a class in its own
right. It can only exist in derived form.</p>
<p>To create a circle class is now easy:</p>
<pre class="programlisting">class circle : public shape<br>{<br>public:<br>  void Draw() { circle(xc, yc, sz); } // or whatever your compiler uses<br>};</pre>
<p>Easy isn't it! All the functionality needed to use the circle,
exists in the abstract shape class, the only thing circle has to do is
draw itself on demand. Likewise Squares and Triangles can be created in
a similar manner.</p>
<pre class="programlisting">class square : public shape<br>{<br>public:<br>  void Draw() { rectangle(xc, yc, xc+sz, yc+sz); }<br>};<br><br>class equilateral : public shape <br>{<br>  void Draw() { /* draw triangle */ }<br>};</pre>
<p>So lets get a little program to drive this lot.</p>
<pre class="programlisting">#define NUMSHAPES 30 <br>void main(void)<br>{<br>  int i;<br>  // Set graphics mode<br><br>  // you should ideally use a list or collection class <br>  // that has the foreach function<br>  shape ashape[NUMSHAPES];<br>  for (i=0; i&lt; NUMSHAPES; i++)<br>  {<br>    switch (i%3) <br>    {<br>      case 0: ashape[i] = new circle(); break; <br>      case 1: ashape[i] = new square(); break; <br>      case 2: ashape[i] = new equilateral(); break;<br>    };<br>    ashape[i]-&gt;set(/* generate 4 random no's for x,y,colour,size*/); <br>  }<br>  for (int j=0; j&lt;100; j++) <br>  {<br>    for (i=0;i&lt;NUMSHAPES;i++) <br>        ashape[i]-&gt;travel();<br>  }<br>    // Switch off graphics mode <br>}</pre>
<p>By deriving from shape you can now draw something a lot more
complicated, a wire-frame ship, car or plane, or even use shape to put
a pixel by pixel drawing based around the X and Y co-ordinates. The
choice is yours.</p>
<p>I hope to receive a number of your implementations for the various
compilers so that they can be included on future disks.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
