    <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  :: Student Code Critique Competition</title>
        <link>https://members.accu.org/index.php/articles/1038</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">Student Code Critiques from CVu journal. + CVu Journal Vol 12, #4 - Jul 2000</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/c184/">Journal Columns</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c183/">Code Critique</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/c77/">CVu</a>

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

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

                    -                        <a href="https://members.accu.org/index.php/articles/c183+125/">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;Student Code Critique Competition</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 07 July 2000 13:15:38 +01:00 or Fri, 07 July 2000 13:15:38 +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="d0e13" id="d0e13"></a></h2>
</div>
<p class="c2"><span class="remark">Prizes for this competition are
provided by Blackwells Bookshops in co-operation with
Addison-Wesley. After I had finished the last issue, I became a
little concerned that the problem code was rather tough for the
average reader of C Vu. I need not have as it produced three
excellent responses and I am awarding two prizes (I wish it could
have been three). FG</span></p>
<p class="c2"><span class="remark">You will find the code for this
issue's competition at the end of this column. Why not make my job
harder (though more rewarding) by sending in an entry this
time.</span></p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e21" id="d0e21"></a>Code from last
issue</h2>
</div>
<p>See last issue. If someone reminds me, I will arrange for a copy
to go on our website.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e26" id="d0e26"></a>The
Entries</h2>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e29" id="d0e29"></a>Entry 1 from Anon
(No name embedded in the text file)</h3>
</div>
<p>A quick scan of the code indicated a few practices which I
consider suspect, and a closer inspection revealed errors. It seems
pertinent therefore to split this critique into two parts.</p>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e34" id="d0e34"></a>Part 1 - First
Impressions</h4>
</div>
<p>From top to bottom, rather than in order of severity then.</p>
<p><span class="bold"><b>Header Guards</b></span>. As a general
rule, do not start any names with underscore. Such ID's are
reserved by the compiler.</p>
<p><span class="bold"><b>Header names</b></span>. On the assumption
you are using a modern, reasonably C++ Standard compliant compiler,
the new header names should be used:</p>
<pre class="programlisting">
&lt;cassert&gt;
&lt;iostream&gt;
</pre>
<p>This will also necessitate stating the <tt class=
"literal">std::</tt> namespace in places where <tt class=
"literal">cout</tt>, <tt class="literal">endl</tt> and <tt class=
"literal">assert</tt> are used.</p>
<p><span class="bold"><b>Protected data</b></span>. I prefer to
avoid this whenever possible. Having non-private data means
<span class="bold"><b>at least</b></span> derived classes can
directly access the data, which breaks your encapsulation. In this
case, however, it seems entirely redundant, since the class cannot
be safely inherited from without a virtual destructor. Even in the
presence of inheritance, you have accessor functions which could be
made virtual, thus safely providing access.</p>
<p><span class="bold"><b>Constructor with default
arguments</b></span>. I would prefer to see a &quot;proper&quot; default
constructor, which uses the initialisation list to default the
member variables, and a separate two-argument constructor with no
default parameters. I will return to this point later.</p>
<p><span class="bold"><b>Uses of const</b></span>. In some places
it is used, in other places (where it should be) it is not. Where
it is used, it appears to be used correctly; it is its absence
which should be checked. For instance, <tt class=
"methodname">operator[]</tt> does not change the object in any way,
and thus should be a const function.</p>
<p><span class="bold"><b>Uses of assert.</b></span> When compiled
without debug information (i.e. production code) <tt class=
"literal">assert</tt> does nothing at all. The fact that this is
not production code is not an excuse; it is endorsing bad practice.
Some uses of <tt class="literal">assert</tt> are acceptable, such
as when testing conditions internal to the class during development
so that they can be removed, but all of the uses in the <tt class=
"classname">Array</tt> class are testing run-time conditions which
could occur in the &quot;real world.&quot; It is safer to use explicit tests
(<tt class="literal">if</tt><tt class="literal">...</tt><tt class=
"literal">else</tt>) constructs. <tt class="literal">assert</tt> is
commonly (always?) a macro which expands to an if statement anyway,
so you are not introducing any code overhead.</p>
<p>From this list, only the issues with <tt class=
"literal">assert</tt> are potentially fatal. A constructor with any
number of default arguments may lead to compile-time ambiguities,
and in this case, may lead to unexpected run-time behaviour.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e110" id="d0e110"></a>Part 2 - Closer
Inspection</h4>
</div>
<p>The first thing I looked into was the default template argument.
The comment gave me a clue, and I closely followed the use of
<tt class="classname">IType</tt> to confirm my suspicion. It is
there solely to demonstrate default template arguments. Consider
what would happen if a different type were used to specialise
<tt class="classname">Array</tt>, e.g. a <tt class=
"classname">string</tt>:</p>
<pre class="programlisting">
Array&lt;char, std::string&gt; my_array;
</pre>
<p>It is not the presence of the two int data members <tt class=
"varname">lobound</tt> and <tt class="varname">hibound</tt> which
make this fail, but their use in conjunction with the template type
in the <tt class="function">outOfRange()</tt> function. If the
index type can be parameterised, then both <tt class=
"varname">lobound</tt> and <tt class="varname">hibound</tt> should
be the same type, but this indicates an associative array. In my
opinion, its existence is obscuring the code for no good
reason.</p>
<p>I want to return to the issue of the multi-argument constructor.
It should be understood that this constructor is actually four
constructors in one function; it is a default constructor (no
arguments), a single argument constructor, and a two argument
constructor. The (very) important point that may be missed is that
it is also a converting (single argument) constructor. The absence
of the explicit keyword here means that a compiler is free to
consider this constructor to convert silently from another type, in
order to make a call to a function. This can lead to hard-to-spot
runtime errors, demonstrated below:</p>
<pre class="programlisting">
class Bad {
public:
  Bad(const double a = 0): size_(a) { }
  double Size () const { return size_; }
private:
  double size_;
};

class Test {
public:
  void Print (const Array &amp; index) 
          { cout &lt;&lt; &quot;Array&quot; &lt;&lt; endl; }
// should have implemented a 
// Print (int x),but forgot to
};

int main (){
  Test t;
  t.Print (10);  
// this involves converting to an double, 
// and then constructing a Bad object 
// from the result.
}
</pre>
<p>This will not only compile, but run, too. It may not, however,
be what you expect, especially if class <tt class=
"classname">Bad</tt> is deeply nested in included files.</p>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e152" id="d0e152"></a>Entry 2 from
Robert Lytton</h3>
</div>
<p>My first impression when I saw the student code critique No.4
was that this is for the C++ gurus. However as a novice, at whom
the exercise could well be aimed, my interpretation of the code may
be of interest. Please note well that my observations may be
incorrect, misguided or ignorant. Please do correct me so that I
may learn.</p>
<p>As the code is part of a exercise set by an instructor I will
break the critique down into four sections, what is trying to be
taught, what is actually being taught, implementing the exercise
and finally what skills and knowledge is being practised. I will
work through the exercise in this order and what follows will act
as a journal of my thoughts.</p>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e159" id="d0e159"></a>What is trying
to be taught:</h4>
</div>
<p>At present I am unsure. I am sure the instructor's pep talk and
fuller instructions would have enlightened me but it is not clear
from the code. I will come back to this question at the end...</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e164" id="d0e164"></a>What is actually
being taught:</h4>
</div>
<p>One of the best ways (but not the only way) to learn is by
example. This code has presented me with an example template class.
In the future, if I need to construct something similar, I may
refer to this class. I may even reuse the code fragment before
hacking it into its new shape.</p>
<p>The following is a list of the unspoken lessons taught by
example. These I have judged as being good 4 or bad 8, but please
do not assume my judgement to be correct.</p>
<p>// header: header.h</p>
<p>4 document the file</p>
<p>8 but no need to give a full description as the code is self
documenting</p>
<pre class="programlisting">
#ifndef _MYARRAY 
#define _MYARRAY
</pre>
<p>4 use header guards to prevent multiple inclusions</p>
<p>4 use uppercase for preprocessor defines</p>
<p>8 it is standard practice to not use initial underscores in
define names (initial underscores are reserved for libraries and
compilers, you may use underscores else where)</p>
<pre class="programlisting">
#include &lt;assert.h&gt;
</pre>
<p>8 use the standard C library (this is depreciated, also the use
of <tt class="literal">&lt;cname&gt;</tt> is preferred over
<tt class="literal">&lt;name.h&gt;</tt>)</p>
<pre class="programlisting">
#include &lt;iostream.h&gt;
</pre>
<p>8 C++ library header files need the trailing .h extension
(<span class="bold"><b>not so!</b></span>)</p>
<p>4 use &lt;...&gt; instead of &quot;...&quot; for library header files</p>
<p>8 include all includes in the interface header (these should be
in the implementation file to reduce the dependencies of the
interface)</p>
<p>8 use <tt class="literal">&lt;iostream&gt;</tt> in header files
(for interfaces that use the iostream, <tt class=
"literal">&lt;iosfwd&gt;</tt> should be used in the header files,
it has enough details)</p>
<pre class="programlisting">
template &lt;class BType, class IType = int&gt;
</pre>
<p>4 make the template general</p>
<p>8 make the template as general as possible (I am unsure why
there is an <tt class="classname">IType</tt>, it seems a little too
general and unnecessary, why not just use an int? If <tt class=
"classname">Itype</tt> is used it will have knock on effect
throughout the implementation and should not be mixed with int)</p>
<pre class="programlisting">
protected:
</pre>
<p>8 use protected for implementation members (these should be
private to this class, in fact they could be removed from the
interface by using a pimpl, pointer to an implementation class that
hold them)</p>
<pre class="programlisting">
int lobound, hibound;
</pre>
<p>8 use implicit conversion (these variables are used to hold
values of type <tt class="classname">IType</tt> and so should be
declared as such, comparison and conversions with <tt class=
"classname">IType</tt>s may/will cause problems!)</p>
<pre class="programlisting">
Array(int SZ = 16, IType lo = 0);
</pre>
<p>4 use sensible default values for when none are specified</p>
<p>8 using all uppercase letters for variables is fine (there are
those who would <span class="bold"><b>only</b></span> use all
uppercase for preprocessor defines)</p>
<pre class="programlisting">
Array(const Array &amp;x);
</pre>
<p>4 use const when passing a parameter as a reference</p>
<pre class="programlisting">
~Array();
</pre>
<p>4 explicit constructors paired with explicit destructor</p>
<pre class="programlisting">
IType lo() const; // return this-&gt;lobound
</pre>
<p>4 make member functions const if they do not alter the state of
the object</p>
<p>8 comments that state the obvious are good (this is an
implementation detail, either put the implementation inline here or
hide it)</p>
<p>8 comments do not need to be accurate (comments if given must be
kept up to date, this comment is <span class=
"bold"><b>wrong</b></span>)</p>
<pre class="programlisting">
BType&amp; operator[](IType i);
</pre>
<p>8 only need to define a non-const member function (you will not
be able to read <tt class="classname">Array</tt> subscripts from a
const object without casting)</p>
<pre class="programlisting">
Array&lt;BType, IType&gt;&amp; operator= (const Array&lt;Btype, IType&gt; &amp;x);
</pre>
<p>8 returned references need not be const (making the return type
const would forces the declaration to be an rvlaue. Would this be
safer here?)</p>
<p>8 need to restate template types (the <tt class=
"literal">&lt;BType, IType&gt;</tt> does not need to be restated
for type <tt class="classname">Array</tt>. However you may state a
new types for <tt class="classname">Array</tt>, that of the object
to be copied, <tt class="literal">template&lt;class BBType,
classIIType&gt; const Array&amp; operator=( const Array&lt;BBType,
IIType&gt;&amp; x))</tt></p>
<pre class="programlisting">
void grow(int);
</pre>
<p>8 no need to add parameter names (add them and make them
helpful)</p>
<pre class="programlisting">
// implementation
</pre>
<p>8 it is OK to place implementation in headers (place it in its
own .c. If this header is included multiple times the code will be
compiled multiple times. Also note that as long as the interface in
the header file stays constant, the implementation file may change
with no need to compile other code. See earlier comments on
<tt class="literal">#include</tt>s and pimpl classes)</p>
<pre class="programlisting">
template&lt;class BType, class IType&gt;
</pre>
<p>4 It is assumed that the implementation has been moved and
therefore the <tt class="literal">template&lt;class BType, class
IType&gt;</tt> will be required before each member definition</p>
<p>4 the default type, <tt class="literal">IType=int</tt>, should
only be stated once, in the header</p>
<pre class="programlisting">
Array&lt;BType, IType&gt;::Array(int SZ, IType lo)
</pre>
<p>4 the default values, <tt class="literal">int SZ=16, Itype
lo=0</tt>, should only be stated once, in the header</p>
<pre class="programlisting">
hibound(lo + SZ -1)
</pre>
<p>8 mixed type arithmetic of unknown types is fine (what if
<tt class="classname">IType</tt> is a signed char? See comments on
the use of <tt class="classname">IType</tt> above)</p>
<p>8 may use previously initialised values (it is OK here as
<tt class="varname">lolound</tt> is declared before <tt class=
"varname">hibound</tt> but they could be swapped around, viz:
<tt class="literal">int hibound, lobound;</tt> and then <tt class=
"varname">hibound</tt> would be initialised first)</p>
<pre class="programlisting">
assert(SZ &gt; 0)
</pre>
<p>8 use <tt class="literal">assert</tt> to trap incorrect values
(<tt class="literal">assert</tt> should be used as a debugging aid.
This line will be removed in a release build when <tt class=
"literal">NDEBUG</tt> is defined and negative values will pass
through the code unhindered. This comment stands for the other
asserts too!)</p>
<pre class="programlisting">
arrayData = new BType[SZ];
assert(arrayData != 0);
</pre>
<p>8 always check the pointer is valid (and if it is not? Either
<tt class="literal">new</tt> will throw an exception or return null
in which case the caller must deal with it!)</p>
<pre class="programlisting">
(*this) = x; // use assignment
</pre>
<p>8 factor out similar code <tt class="literal">( (*this) = x ==
(*this).operator=(x) == this-&gt;operator=(x) == operator=(x)</tt>
but is this the way to do it? Is it safe to use this in a
constructor?)</p>
<pre class="programlisting">
cout &lt;&lt; &quot;Array index &quot; &lt;&lt; i &lt;&lt; endl;
</pre>
<p>4 use <tt class="literal">endl</tt> to force a '\n' and flush
the stream</p>
<p>8 no need to state using namespace std (either state it or use
<tt class="classname">std::cout</tt> and <tt class=
"literal">std::endl</tt>)</p>
<p>8 the called should report (this restricts the usefulness of the
member function and reporting would be better handled, if desired,
by the caller)</p>
<p>4 <tt class="classname">IType</tt> will handle the <tt class=
"literal">cout&lt;&lt;</tt> or we will get a compile time</p>
<pre class="programlisting">
errorassert (hibound-lobound 
      == x.hibound-x.lobound);
</pre>
<p>8 restrict usage (see comment above about <tt class=
"literal">assert</tt>, also the code could be made to handle
different sized arrays)</p>
<pre class="programlisting">
arrayData[i] = const_cast&lt;
    Array&lt;BType, IType&gt;&amp;&gt;(x).arrayData[i];
</pre>
<p>8 use <tt class="literal">const_cast</tt> to force read access
of const objects (we should not need to use a <tt class=
"literal">const_cast</tt>, unless <tt class="classname">Btype</tt>
does not have an <tt class="methodname">operator[] const</tt>
member, see comments above about <tt class=
"methodname">operator[]</tt>)</p>
<p>8 use interface to access implementation (in this case it seems
excessive, as this is a private implementation we could directly
access the data and use <tt class="function">copy()</tt>)</p>
<p>8 don't worry about roll back (this is not exception
neutral)</p>
<p>There may be other subtle lessons I am being taught through this
code that I am unaware of. As a novice I would welcome corrective
comments. As an aside you may be interested to know that I
initially learnt C from <span class="bold"><b>H.Schilt</b></span>
and may still have lessons that need unlearning.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e437" id="d0e437"></a>Implementing the
exercise:</h4>
</div>
<p>These implementations try to follow the style of the code used
already!</p>
<pre class="programlisting">
// idea 1
template &lt;class BType, class IType&gt;
void Array&lt;BType, IType&gt;::grow(int newS)
{
  assert(newS &gt;= hibound-lobound);
// implicit conversion. 
// No checking done if NDEBUG is defined
  BType* newarrayData = new BType [newS];
  assert( newarrayData != 0); 
// no checking done if NDEBUG is defined
// similar code as operator=, hopefully
// hibound - lobound is less than INT_MAX
  for(int i = 0; i&lt;= hibound - lobound; ++i)
    newarrayData[i] = (*this).arrayData[i];
  ~Array();        // delete old data
  arrayData=newarrayData; // insert new data
  hibound = lobound - newS + 1;// new length
  cout &lt;&lt; &quot;done&quot; &lt;&lt; endl;  
    // I just couldn't resist!
}

// idea 2
template &lt;class BType, class IType&gt;
void Array&lt;BType, IType&gt;::grow(int newS)
{
  assert(newS &gt;= hibound-lobound);
  // implicit cast, don't add any further 
  // run time checking
  Array tempArray(newS,lobound);  
  // object of new length
  int swaphibound = tempArray.hibound; 
// keep record for later
  tempArray.hibound = hibound;  
// force to same size
  tempArray = (*this);    
// and copy data across using operator=
  BType *swaparrayData = arrayData;  
// swap the blocks over
  arrayData = tempArray.arrayData;
  tempArray.arrayData = swaparrayData;
  hibound = swaphibound;    
// and fix the extended size the old data will
// be destroyed when tempArray goes out of scope
}
</pre>
<p>N.B. In true student style, I have not tried to compile the two
submissions. I think this is justifiable, the exercise would not
have compiled either without alterations. (I did say the
implementations would follow the style of the code!)</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e446" id="d0e446"></a>What
skills/knowledge is being practised:</h4>
</div>
<p>As I knew the code was poor I found myself carefully checking
the syntax against the <i class="citetitle">C++ Programming
Language</i>, which I found of great value. However in the context
of the exercise I found myself practising the poor techniques that
had been presented. The exercise could have been an opportunity to
practise and become more familiar with a classic design pattern,
something that I need to do. As it is I have only become familiar
and worked with some very dubious methodologies.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e454" id="d0e454"></a>What is trying
to be taught - take2:</h4>
</div>
<p>After working through the whole exercise I still have no
answers, except, bad habits. I will now go and purify my mind by
reading what <i class="citetitle">C++ Programming Language</i> has
to say about templates. I really must buy <i class=
"citetitle">Design Patterns</i>.</p>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e465" id="d0e465"></a>Entry 3 from
Oliver Wigley</h3>
</div>
<p>In an attempt to assess the student code for the May
competition, I have commented on the design and limitations of the
class itself, and on any other general issues arising from the
code. As an array class (especially as one called <tt class=
"classname">Array</tt> - suggesting an all-encompassing approach)
it should ideally be written to cover a multitude of applications
by implementing a simple and intuitive public interface that
simulates regular arrays.</p>
<p>The example uses a <tt class="literal">#define</tt> directive to
prevent multiple parsing of the header file at compile time:</p>
<pre class="programlisting">
#ifndef _MYARRAY
#define _MYARRAY
</pre>
<p>Whilst code examples frequently use identifiers and function
names like <tt class="function">myfunc()</tt>, <tt class=
"function">yourfunc()</tt>, <tt class="constant">_MYCONSTANT</tt>,
it is generally understood that this is not what is done in
practice, since it could very quickly lead to name clashes,
especially - as in this example - in the absence of the use of
namspaces. After all, the only reason this <tt class=
"literal">#define</tt> directive exists is to test the definition
of a universally unique identifier, so some effort should be made
to ensure that is unique.</p>
<p>The template class illustrates how a default type can be used in
the declaration:</p>
<pre class="programlisting">
template &lt;class BType, class IType = int&gt; 
class Array{...}
</pre>
<p><tt class="literal">class BType</tt> is the type that is to be
stored in the internal array, and <tt class="literal">class
IType</tt> is the type used to access elements in the array through
<tt class="methodname">operator[]</tt>. There are no instances
where the latter type should behave as anything other than an
integral type. Subsequently, as long as appropriate conversions are
available for the type you use here, the compiler will happily
generate the necessary code. For example, this generic class
template lets me do the following:</p>
<pre class="programlisting">
Array&lt;int,char&gt; obj(10,'k');
for(char n = obj.lo(); n&lt;=obj.hi();++n)
  obj[n]='m';
</pre>
<p>The <tt class="classname">IType</tt> value (here, a char) passed
into the constructor is used to initialise the <tt class=
"varname">lobound</tt> data member (an int). Its integral
equivalent is returned by <tt class="methodname">lo()</tt>, and is
used for <tt class="methodname">operator[]</tt> indexing. Access to
the array becomes 'k' - based rather than 0-based.</p>
<p>Whilst initially this would seem to offer some kind of
flexibility to the class, assumptions about the type have been
made. With <tt class="classname">IType</tt> being a char, for
example, I doubt if the code will behave as expected if the call to
<tt class="classname">cout</tt> in the <tt class=
"methodname">outofRange()</tt> function is ever reached:</p>
<pre class="programlisting">
bool Array&lt;BType, IType&gt;::outofrange(IType i){
  if(i&lt;lobound || i&gt;hibound){
    cout &lt;&lt; &quot;Array index &quot; &lt;&lt; i 
         &lt;&lt; &quot;is out of range&quot; &lt;&lt; endl;  
    return true;
  }
else return false;
}
</pre>
<p>Why anyone should be able (or even want) to do this, I could not
say. It is a dubious feature of the class as it stands, and smacks
of a 'doing something just because you can' approach.</p>
<p>The class uses a <tt class="varname">hibound</tt> / <tt class=
"varname">lobound</tt> paradigm for array access, which is not the
expected behaviour in an array, and introduces unnecessary
complexity. It also reduces encapsulation by exposing
implementation details. I would much rather the <tt class=
"classname">IType</tt> parameter were disposed with altogether, and
implement array access to resemble access of normal array types
(i.e.: 0-based array access with <tt class=
"methodname">operator[]</tt> and integral types). The <tt class=
"classname">IType</tt> value and <tt class="varname">lobound</tt> /
<tt class="varname">hibound</tt> treatment in the class together
suggest poor abstraction, resulting in an array class that looks
like it is already specialised for a specific purpose, and has then
simply been template-ised. Apart from anything else, it makes
iterations through the list unintuitive:</p>
<pre class="programlisting">
const unsigned int array_size = 12;
const int lowerbounds = -4;
Array&lt;int,int&gt; array_obj(array_size,lowerbounds);
for(int p = 0; p&lt; array_size; p++)
  array_obj[p] = get_input();  //error
for(p = array_obj.lo(); 
     p&lt;=array_obj.hi(); p++)
  array_obj[p] = get_input();  //like this
</pre>
<p>As far as the classes' public interface is concerned, it should
allow access just like any other array. To do this it would need an
int <tt class="function">getsize()</tt> - type function, and access
would look something like this:</p>
<pre class="programlisting">
for( int p = 0; p &lt; array_obj.getsize(); p++ )
  process_data( array_obj[p] );
</pre>
<p>The default constructor declaration (<tt class=
"literal">Array::Array(int SZ = 16, Itype lo = 0)</tt>) could be
smartened in several ways. The use of the magic number 16 has no
obvious foundation, and is certainly not a very generic
implementation. A descriptive constant would clarify what the
reasoning was here, even if it was called <tt class=
"constant">MyRandomDefaultValue</tt>. Also, the use of a signed
value for <tt class="varname">SZ</tt> is pointless - signed ints
are too frequently the default choice where unsigned ones will
avoid problems and will improve readability too. A look at the
constructor shows that some effort has been made to deal with this
predicament (<tt class="literal">assert(SZ&gt;0)</tt>), though the
handling of this could have been more helpful. An abnormal program
termination brings this to light in debug mode, and is compiled to
nothing in a production compilation. Although I would have limited
this argument to an unsigned int, and would also have allowed the
construction of 0-length arrays anyway, exception throwing might
have been a more useful way to deal with values less than 1, giving
the possibility of recovery from an incorrect initialisation.</p>
<p>The naming convention used for the arguments (<tt class=
"varname">SZ</tt> and <tt class="varname">lo</tt>) is inconsistent
and ambiguous. An all upper case identifier suggests a
pre-processor macro or constant: size would be better for the
<tt class="varname">SZ</tt> argument. Both parameters should have
const qualifiers, too.</p>
<p>With this constructor an array with any number of elements is
constructed, memory is allocated, and the default constructor for
those objects is called. An array created like this is probably not
going to be much use to anyone until each member has been
initialised with something specific - and there is currently no way
for the client code to test whether or not an array item is
anything but a default object. Of course this may be exactly what
you want, and is fine if everyone using the class remembers to do
this, but as a generic template class it is rather suspicious
(<i><span class="remark">but that is the way STL containers work.
FG</span></i>). I would rather by default construct an empty array
(getting rid of the <tt class="varname">SZ</tt> parameter
altogether) whose contents are grown and initialised with specific
objects that can be retrieved as something useful straight away.
The limitation of not being able to increase or initialise the
array with something other than a default construction in a single
function call is compounded in the <tt class="function">grow()</tt>
function argument, which also forces default construction:</p>
<pre class="programlisting">
template &lt;BType, IType &gt; 
void Array::grow(int newS){/*...*/}
</pre>
<p>I would have preferred to have had an <tt class=
"literal">Add(const BType&amp; item)</tt> - type function being
supplied, which increases the size of the internal array by one,
and initialised the object with the item passed in. Not allowing an
array of 0-length to be created in the constructor is a limitation
in the design, and makes the class inflexible.</p>
<p>The use of the new operator is inconsistent, and wrong unless we
happen to be working with an old compiler. In the constructor we
are given:</p>
<pre class="programlisting">
arrayData=new BType[SZ]; 
assert(arrayData!=0);
</pre>
<p>There is no such check in the copy constructor. In any case, the
check for the null pointer being returned by new is wrong, as new
is guaranteed to return something else. A <tt class=
"classname">std::bad_alloc</tt> object (or derivation of) is thrown
(rather 'should' be thrown - my compiler throws something
different) if the requested memory cannot be allocated. So if
anything, try and catch blocks are needed to handle the failure.
There is a compatibility issue here, since old compilers may not
support this behaviour, in which case you could simulate the same
effect by installing (and then uninstalling) a new-handler function
(using <tt class="function">set_new_handler()</tt>).</p>
<p>There is no <tt class="methodname">operator[]</tt> provision for
const objects. The given one should be overloaded with a const
version, which would return elements by value. Methods <tt class=
"methodname">lo()</tt> and <tt class="methodname">hi()</tt> are
const, so some consideration has been given to const-ness, but some
functions have been overlooked. Another contender for const-ness
would be <tt class="methodname">OutOfRange(IType i)</tt> - which
could then be called from <tt class="methodname">operator[] (IType
i) const</tt> (although this should really be <tt class=
"methodname">operator[] (int i) const</tt>).</p>
<p>The assignment operator fails the first rule of assignment
operators: there is no check for self-assignment (<i><span class=
"remark">nor does it use the alternative idiom. FG</span></i>).
This takes no time to implement, and is a good thing to do.
Conceptually there are two ways to approach this: either check that
an object isn't being assigned to itself, or check that the two
separate objects aren't to all intents and purposes the same (e.g.:
<tt class="literal">string a (&quot;hello&quot;), b (&quot;hello&quot;); a = b;</tt>).
I have never seen the latter type of check, and am still
unconvinced about its benefits, but it may as well be mentioned
since it is apparently used.</p>
<p>The assignment operator is also odd in that the objects are
required to be the same length for assignment to be successful.
This is a limitation for any array class, let alone a template
class. To avoid the assertion in this function you would need to
verify the sizes of the two arrays before attempting to call it.
This highlights that there is also no convenient <tt class=
"methodname">size_t length()</tt> - type member function.
Presumably this is what you are expected to do with the code
given:</p>
<pre class="programlisting">
if(a.hi()-a.lo()==b.hi()-b.lo()) {
      /*go ahead with copy*/ }
else {/*resize our object maybe*/} 
</pre>
<p>To avoid this limitation in the <tt class=
"methodname">operator=</tt>, memory could have been allocated for
the new array, initialised it accordingly, then deleted the old
memory. Because there is no <tt class="methodname">operator[]</tt>
for const objects, <tt class="literal">const_cast</tt> is used on
the source object. As it stands, the use is harmless enough.
However, since we are striving for exemplar code, then we should
avoid the use of const_cast. You could be forgiven for thinking if
this is allowed:</p>
<pre class="programlisting">
arrayData[i]=const_cast&lt;Array&lt;BType,IType&gt;&amp;&gt;
            (x).arrayData[i];
</pre>
<p>then this must also be allowed:</p>
<pre class="programlisting">
const_cast&lt;Array&lt;BType,IType&gt;&amp;&gt;
    (x).arrayData[i]=arrayData[i];   //woops
</pre>
<p>The assignment operator is incomplete in that the <tt class=
"varname">lobound</tt> and <tt class="varname">hibound</tt> members
are not re-initialised. This may be the required behaviour in the
client code, but contradicts the usual expectations in of an
assignment operator, and is definitely unsuitable in a generic
class of any sort.</p>
<p>The problems the students have in finishing the <tt class=
"function">grow()</tt> function are twofold: firstly, given the
function name and signature - what should the function do, and
secondly making the code tally with the behaviour of the rest of
the class. The problem is not &quot;What would a <tt class=
"function">grow()</tt> function do in a template array class I
would write?&quot;, but rather &quot;What does the writer of this class
expect the <tt class="function">grow()</tt> function to do?&quot;. The
implementation I would propose would aim to be consistent with the
rest of the code, rather than try to impose a different approach.
To not try and write what is expected would almost certainly break
the source code that the instructor is going to compile it
with.</p>
<p>The two possible meanings that could be read into the function
prototype are:</p>
<pre class="programlisting">
void Array&lt;BType, IType&gt;::resetsize(unsigned int newsize)  /*reset the size to this value*/
</pre>
<p>or</p>
<pre class="programlisting">
void Array&lt;BType, IType&gt;::change(int growby) /*change size by this amount*/
</pre>
<p>Since the given function is</p>
<pre class="programlisting">
void Array&lt;BType, IType&gt;::grow(
                    int newS /*new size*/)
</pre>
<p>I imagine that what is expected is for the array to be reset to
the new size passed in. Given the name of the function, and the
rest of the code given, <i class="parameter"><tt>newS</tt></i> is
probably anticipated to be larger than the current size of the
array, so I would expect to see this early in the function:</p>
<pre class="programlisting">
assert( newS &gt; hibound-lobound+1);
</pre>
<p>The current state of the array as it stands would be maintained,
and default objects constructed for the extra elements:</p>
<pre class="programlisting">
BType* oldData = arrayData;
arrayData = new BType[newS];
for(int p=0; (p&lt;newS) &amp;&amp; 
          (p&lt;(hibound-lobound+1)) ;p++)
    arrayData[p]=oldData[p];
delete [] oldData;
hibound = lobound + newS - 1 ;
</pre>
<p>Given the limitations of <tt class="methodname">operator=</tt>,
the <tt class="varname">lobound</tt> / <tt class=
"varname">hibound</tt> stuff, the magic numbers, and magic types
(<tt class="literal">IType = int</tt>), I would say that this class
is an already specialised array class, thinly veiled as a generic
template class. As such is it a poor illustration of a truly
generic array class.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e734" id="d0e734"></a>Prize
Winners</h2>
</div>
<p>If Oliver and Robert like to contact me, we can discuss the
issue of prizes</p>
<p>Congratulations to them both. Now, check their comments and make
sure you agree. If you just take their word for it, you willbe
neither helping yourself nor them. Remember that one of the main
reasons that this column appears in this section is that it is
supposed to be part of a seminar like dialgue between readers. In
general, I do not comment on dubious statements in a published
critique; that is your job.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e741" id="d0e741"></a>Competition
No 5</h2>
</div>
<p><span class="bold"><b>sponsored by Blackwells Bookshops &amp;
Addison Wesley</b></span></p>
<p>Rather simpler this time. I change the identifiers to English
apart from one that means nothing to me. Any German readers want to
tell me what it means? Your critique should focus on the code
rather than just the students stated problem.</p>
<p>As always there will be a prize provided by Blackwell's
Bookshops in collaboration with Addison-Wesley. If other
booksellers and/or publishers would like to sponsor one of our
columns, I would be very happy to discuss it with them.</p>
<p>Entries by August 14th.</p>
<pre class="programlisting">
class Book {
public:
  virtual void details();
  void details(char* , char *, float ); //Author, Title,Pages
  virtual void anzeigen();
  Book();     ~Book();
  Book(char*, char *, float);
  Book(const Book&amp;);
  Book&amp; operator=(const Book&amp;);
  bool operator== (const Book&amp; );
protected:
  struct book {
    char* title;
    char* author;
  float price; } b;
};
</pre>
<p>and the class:</p>
<pre class="programlisting">
class ChildBook: public Book {
public:
  int reading_age;
  virtual void details();
  void details(char* , char *, float ,int);
    //author, title, pages
  virtual void anzeigen();
  ChildBook();
  ChildBook(char*, char *, float, int);
  ChildBook(const ChildBook&amp;);
  ~ChildBook();
  ChildBook&amp; operator=(const ChildBook&amp;);
  bool operator== (const ChildBook&amp;);
};
Furthermore, there is the class
class BookList: public Book {
public:
  Book b;
  ChildBook k;
  list&lt;Book&gt; Book;
  list&lt;ChildBook&gt; kiBook;
  void details();
  void anzeigen();
  ~BookList();
  BookList();
  };
which also derives from Book. It should represent a kind of Library.
In the main()-function I make an instance of class BookList and assign different values to the components:
BookList bue;
//one component for Book
bue.Book.push_back(Book(&quot;Book&quot;,&quot;Title&quot;,20));
//one component for ChildBook
bue.kiBook.push_back(ChildBook(&quot;Author&quot;
      ,&quot;Title&quot;,35,5));   
If I walk trough the program using the debugger, I can see that the list-entry for Book is created rightly, whereas the entry for ChildBook is destroyed immediately after creation. Every time after creating, the destructor is launched - why? At the component Book it is all correctly (in spite of launching the destructor!). For the ChildBook-object it seems that the wrong entry is deleted. There are some constructors of the classes
Book::Book() {
  b.author = new char[10];
  strcpy(b.author,&quot;Author&quot;);
  b.title = new char[10];
  strcpy(b.title,&quot;Title&quot;);
  b.price = 0.00f;
}

Book::Book(char * t, char * a, float p) {
  b.author = new char[strlen(a)+1];
  b.title = new char[strlen(t)+1];
  strcpy(b.author,a);
  strcpy(b.title,t);
  b.price = p;
}

Book::Book(const Book&amp; p) {
  b.title = new char[strlen(p.b.title)+1];
  strcpy(b.title,p.b.title) ;
  b.author = new char[strlen(p.b.author)+1];
  strcpy(b.author,p.b.author) ;
  b.price = p.b.price;
}
Book::~Book () {
  delete b.title;
  delete b.author;
}

ChildBook::ChildBook() {reading_age=3;}
ChildBook::~ChildBook() {  }
ChildBook::ChildBook(char * t, char * a,
       float p, int la) : Book(t,a,p){
  reading_age=la;
}

ChildBook::ChildBook(const ChildBook&amp; k){   b=k.b;
  reading_age=k.reading_age;
}

BookList::BookList(){ }
BookList::~BookList(){ }
</pre></div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
