    <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 6</title>
        <link>https://members.accu.org/index.php/articles/1083</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, #6 - Dec 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/c123/">126</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c183+123/">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 6</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 06 December 2000 13:15:42 +00:00 or Wed, 06 December 2000 13:15:42 +00: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>Student Code
Critique Competition</h2>
</div>
<p class="c2"><span class="remark">Prizes for this competition are
provided by Blackwells Bookshops in co-operation with Addison
Wesley. Note: that I have a couple of prizes waiting for me to get
round to posting them (with luck, I may get them in the post before
you get this) however if you won a prize and have not received it
by December 15th please contact me so that I can get all
outstanding prizes cleared before the New Year.</span></p>
<p class="c2"><span class="remark">Not to keep you in suspense,
Chris Main is the winner this time (despite a tour de force from my
most regular contributor, Steve Love)</span></p>
<p class="c2"><span class="remark">Note that the code being
critiqued is on our website (together with Steve Love's code and
that for Competition 7)</span></p>
<p class="c2"><span class="remark">Francis Glassborow</span></p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e33" id="d0e33"></a>Critique No
6</h2>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e36" id="d0e36"></a>Critique from
Chris Main</h3>
</div>
<p>&quot;Why did you implement <tt class="classname">BookList</tt> like
that?&quot; complained Tim Leader. &quot;I can add <tt class=
"classname">Book</tt>s and <tt class="classname">ChildBook</tt>s to
the list, but I can only remove them as <tt class=
"classname">BookBase</tt>s that have no methods. What use is
that?&quot;</p>
<p>&quot;I know, it's ridiculous&quot;, replied Nathan, &quot;but you stated in
the design model that it's supposed to follow the Composite design
pattern.&quot;</p>
<p>&quot;Oh take no notice of that,&quot; said Tim Leader. &quot;Des Authority
read a book on patterns and then mandated that every class in the
model had to have an attribute mapping it to a pattern. It's not
appropriate in most cases, but you can't tell him that so I just
fill the attributes in randomly.&quot;</p>
<p>Relieved, Nathan deleted the <tt class="classname">BookBase</tt>
class and made <tt class="classname">BookList</tt> a <tt class=
"type">typedef</tt> for <tt class="type">list&lt;Book&gt;</tt>.
Just to be on the safe side, he thought he would write some unit
tests. Tim's view is that if he &quot;gets the design right&quot;
implementation is trivial, so unit testing is unnecessary, and
anyway there isn't time for it. Nathan isn't convinced. His tests
showed that he could get items back from the list as <tt class=
"classname">Book</tt>s, with titles, authors and prices unchanged
from when they were added to the list. How reassuring. Maybe he
could get some mileage from a few more tests. He checked the
default constructor for <tt class="classname">Book</tt>. <tt class=
"function">title()</tt> and <tt class="function">author()</tt>
returned null pointers, not the null string. Whoops! He had used
single quotes instead of double in the constructor member
initialisers. Obviously this was a typing slip as he hadn't done
the same for <tt class="classname">ChildBook</tt>. He noticed that
he could also delete the existing default constructor for
<tt class="classname">Book</tt> by adding default values to the
other constructor. For tidiness he used &quot;&quot; rather than &quot;<tt class=
"literal">\0</tt>&quot; for the null string. After this fix, everything
went fine until he had the idea to try to assign a <tt class=
"classname">Book</tt> object to itself. Access violation! Null
pointer! He added</p>
<pre class="programlisting">
if(this != &amp;your_book) { ... }
</pre>
<p>to the assignment operators to prevent this [<span class=
"editorial">if he ever gets to go on one of my courses, he will
learn a better, exception safe, idiom. Francis</span>]. While he
was about it, in <tt class="function">deleteStuff()</tt> he added
checks that the pointers were not null before attempting to delete
them and set them to 0 after deletion. Now everything ran smoothly.
[<span class="editorial">It was several months latter that he
discovered that delete expressions already check for null pointers.
F</span>]</p>
<p>A few days later, Nathan was bored. Tim Leader was &quot;gathering
requirements&quot; and after that he would be &quot;getting the design
right&quot;. It would be weeks before he had any work to pass on to
Nathan, so Nathan settled down to studying <i class=
"citetitle">Stroustrup's 3rd Edition</i> in the hope he would
discover ways of further improving his code. He started with const;
the access functions didn't look quite right. Clearly returning
<tt class="type">const char *</tt> for <tt class=
"function">title()</tt> and <tt class="function">author()</tt> is
correct since the internal members are being returned and clients
must be prevented from modifying their values. But the other
<tt class="literal">const</tt> (even if it had been the correct
side of the <tt class="literal">*</tt>) serves no purpose. What was
really needed was for the functions themselves to be qualified by
<tt class="literal">const</tt>, since they do not modify member
data. Likewise <tt class="function">price()</tt> and <tt class=
"function">operator ==()</tt> should be <tt class=
"literal">const</tt> functions. <tt class="function">price()</tt>
returns a <tt class="type">double</tt> by value, not by address, so
it is unnecessary for its return type to be qualified by <tt class=
"literal">const</tt>.</p>
<p>What about the modification functions? Nathan had dutifully
followed Tim's design specification, but surely a book's title and
author are intrinsic to its identity, and so should not be
modifiable? He decided to delete them, and renamed <tt class=
"function">price()</tt> to <tt class="function">set_price()</tt> so
that it would not be confused with the access function by human
readers.</p>
<p>He found a neater way of implementing the data manipulation
functions. He made them private and non-virtual in <tt class=
"classname">Book</tt>. Then in <tt class="classname">ChildBook</tt>
he deleted the corresponding functions and used the assignment from
<tt class="classname">Book</tt> in the assignment for <tt class=
"classname">ChildBook</tt>:</p>
<pre class="programlisting">
if(this != &amp;your_book) {
    Book::operator=(your_book);
    my_reading_age = your_book.my_reading_age; }
return *this;
</pre>
<p>He used the same idea in <tt class="function">operator==()</tt>;
this meant that he could make all the data members private, too,
improving the encapsulation of the classes.</p>
<p>The code common to the Book constructor and <tt class=
"function">copyStuff()</tt> was factored out into another private
member function:</p>
<pre class="programlisting">
void copyStuff(const char *title, 
       const char *author, double price);
</pre>
<p>In looking more carefully at this code, he discovered that the
standard requires his calls of new to be qualified by (<tt class=
"literal">std::nothrow</tt>) if he is to use them this way i.e.
checking whether a null pointer is returned. However his compiler
didn't support this qualification but the code did work as he had
written it.</p>
<p>Having improved the implementation, Nathan looked at the bigger
picture. He wrapped his classes in namespace publication, and
replaced the friend <tt class="function">operator&lt;&lt;()</tt>
member functions with functions like:</p>
<pre class="programlisting">
ostream &amp;output(ostream &amp;);
</pre>
<p>Then, outside the classes but within the namespace he declared
the <tt class="function">operator&lt;&lt;()</tt> functions and
implemented them by calling the respective <tt class=
"function">output()</tt> member functions. Access to his classes
was no longer compromised by their friends.</p>
<p>Finally he reinstated <tt class="classname">BookBase</tt> as an
abstract class, declaring <tt class="function">title()</tt>,
<tt class="function">author()</tt>, <tt class=
"function">price()</tt> and <tt class="function">set_price()</tt>
as pure virtual functions. He derived <tt class=
"classname">Book</tt> from <tt class="classname">BookBase</tt> and
changed <tt class="classname">BookList</tt> to <tt class=
"type">list&lt;BookBase *&gt;</tt>. At a stroke he had reduced the
dependency of clients upon concrete classes in his namespace, and
hence reduced the impact upon clients of any future changes made to
those concrete classes.</p>
<p>In the abstract <tt class="classname">BookBase</tt> class he
also declared a virtual destructor with an empty implementation
(not pure). This eliminated the major bug that had so far escaped
his attention: a <tt class="classname">ChildBook</tt> can be added
to <tt class="type">list&lt;Book&gt;</tt> but when that list is
destroyed the <tt class="classname">Book</tt> destructor is called,
not the <tt class="classname">ChildBook</tt> destructor. Even if
<tt class="classname">BookList</tt> is declared as <tt class=
"type">list&lt;Book *&gt;</tt> the <tt class="classname">Book</tt>
destructor is called for <tt class="classname">ChildBook</tt>s,
because the destructor in <tt class="classname">Book</tt> is not
declared virtual. No harm had come from this omission yet because
no resources are allocated in the <tt class=
"classname">ChildBook</tt> constructor over and above those
allocated by the <tt class="classname">Book</tt> constructor. But
having ridden his luck this far, Nathan did the decent thing and
made the destructors in <tt class="classname">Book</tt> and
<tt class="classname">ChildBook</tt> virtual (he also made the
functions <tt class="function">title()</tt>, <tt class=
"function">author()</tt>, <tt class="function">price()</tt> and
<tt class="function">set_price()</tt> explicitly virtual for
tidiness).</p>
<p>When Tim Leader eventually got back to using Nathan's code he
was amazed. At first he had doubts about the namespace, arguing
that it was a Microsoft specific feature only really useful for
resolving name clashes. He only yielded when Nathan showed him
chapter and verse from Stroustrup. He thought the abstract class
was wonderful, and set off to enlighten the rest of the
project.</p>
<p>One day, Del Iverymanager called Tim Leader into his office. &quot;As
you know, Des Authority is leaving us to join yadotcom.com. Since
you came up with that great idea of using abstract classes, I think
you're the man to take on his role. What about Nathan, do you think
he could do your job?&quot;</p>
<p>&quot;No, I don't think so&quot;, Tim shook his head, &quot;he's not up to
speed with C++, has to keep referring to that book of his.&quot;</p>
<p>&quot;I suppose you're right&quot;, agreed Del knowingly, &quot;I had noticed
that his subsystem has fewer lines of code now than a month ago,
and according to my planning tool that means the project has
slipped another six weeks.&quot;</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e298" id="d0e298"></a>Critique from
Steve Love</h3>
</div>
<p>We start well here, with good intentions at least. In the light
of almost all of Overload 39, particularly Kevlin Henney's
&quot;<i class="citetitle">Source Cohesion &amp; Decoupling</i>&quot;
(<a href="#Henney2000">Henney2000</a>), we have an include guard,
in all capitals, reflecting the name of the file.</p>
<p>Forward declaring a class so that its complete declaration need
not be included is laudable, but in the case of template classes
(the stream classes are all templates in modern compilers - I note
here that Francis already mentioned the use of a pre-standard
compiler) it is difficult, if not quite impossible, to provide the
complete declaration. The header <tt class=
"literal">&lt;iosfwd&gt;</tt> is provided for this express purpose,
however, and has the same effect.</p>
<p>An empty class can only signify a base class. An empty base
class, to my mind, indicates a design flaw; perhaps this is what
Francis alludes to. Any classes derived from this empty class can
be seen through a pointer to the base class. However, the base
class being empty, this pointer would have to be cast to the static
type anyway for it to be of any use. Having a common base class
indicates further that such a pointer's static type may be
variable, in this case it could be a <tt class=
"classname">Book</tt>, a <tt class="classname">BookList</tt>, or a
<tt class="classname">ChildBook</tt>. Actually casting to the
<tt class="type">static</tt> type would involve what is to me a
misuse of RTTI information. So much for empty base classes. I will
not yet rule out the possibility of a common base class for some of
this hierarchy however.</p>
<p>Looking into class <tt class="classname">Book</tt>, then. First
up, a constructor with multiple parameters. Two <tt class=
"type">char*</tt>s, evidently indicating strings of some kind.
These should definitely be <tt class="type">const</tt>, since they
must be copied to data members of the <tt class=
"classname">Book</tt> class in order to be safe. Looking ahead,
these data members exist, and they are indeed copied from these
arguments. Using <tt class="classname">std::string</tt> or a
similar &quot;value&quot; class would have benefits here, and remove some
sources of error. Even then, they should be const references.</p>
<p>There is also a default parameter. This has the effect of making
this two constructors in one, although in this case I do not see
any real problem with that (it is not my preference). I will return
to this point later.</p>
<p>The void parameter for the default constructor and destructor is
redundant in both cases. Again, this may be the compiler's
fault.</p>
<p>Rather more serious is the default constructor's initialisation
list. <tt class="varname">my_title</tt> and <tt class=
"varname">my_author</tt> are both <tt class="type">char*</tt>s.
<tt class="literal">char * c('\0')</tt> achieves the same result as
<tt class="literal">char * s = 0</tt>; this may be the intention,
but leads to errors elsewhere. Importantly it does not set the
contents of the string to be a single <tt class="literal">null</tt>
character.</p>
<p>The destructor for <tt class="classname">Book</tt> should be
virtual. Since <tt class="classname">Book</tt> is used as a base
class for <tt class="classname">ChildBook</tt>, and more
particularly since it requires a defined destructor to free up
memory for the strings, the absence of a virtual destructor may
result in serious memory leaks.</p>
<p>The copy assignment operator suffers from one anti-idiom:
&quot;release before copy.&quot; Just swapping the two function calls would
not work either. This needs a little expansion.</p>
<p><tt class="methodname">deleteStuff()</tt> is fine. It uses the
correct versions of <tt class="methodname">delete[]</tt>, but, to
risk harping on, would not be needed if <tt class=
"classname">std::string</tt> had been available.</p>
<p><tt class="methodname">copyStuff()</tt> is less secure, and
suffers from basically the same problems experienced by the
original code. Memory is allocated, data is copied, memory is
allocated, data is copied. If the second allocation fails, memory
allocated before it is leaked. Again, a pre-standard compiler
appears to be indicating memory allocation failures by setting the
pointer to <tt class="literal">0</tt> instead of throwing an
exception. In this case, if the second allocation fails, then
<tt class="classname">Book</tt> is left in an inconsistent
state.</p>
<p>More seriously, if the <tt class="classname">Book</tt> being
passed in to <tt class="classname">copyStuff()</tt> had only been
default-constructed (recall that the default constructor set all
strings to <tt class="literal">0</tt>), we have undefined
behaviour, as these pointers are dereferenced in the call to
<tt class="methodname">strlen()</tt>.</p>
<p>In order for copy assignment to be made safe in the presence of
memory allocation failure, we need to perform the copy before the
release (CBR) (<a href="#Henney1998">Henney1998</a>). By making use
of a temporary <tt class="classname">Book</tt> object, we can
construct it with the values to be copied, allocate new space,
release the old space, and finally copy the temporary values into
this space. The simple idiomatic way of doing this is well
documented elsewhere, but put simply, assuming an existing
<tt class="methodname">swap</tt> function for <tt class=
"classname">Book</tt> types:</p>
<pre class="programlisting">
const Book&amp; Book::operator=(const Book &amp; rhs){
    swap (*this, Book (rhs));
    return *this;
}
</pre>
<p>The temporary <tt class="classname">Book</tt> created in the
call to swap is destroyed on exit from the function, so the
original memory is freed after everything else has been copied
successfully. If the swap fails, then this is left in the same
state as before the copy assignment was invoked.</p>
<p>Both <tt class="methodname">deleteStuff()</tt> and <tt class=
"methodname">copyStuff()</tt> are virtual and protected. The reason
for virtual is clever, but unnecessary I think, besides which, the
virtual-ness of the functions is never used. Given that both
<tt class="classname">Book</tt> and its immediate child class,
<tt class="classname">ChildBook</tt>, define copy assignment
anyway, the contents of these functions may as well be placed
there; the extra level of indirection is unnecessary.</p>
<p>The equality comparison operator should be a const function.
Lastly, the use of protected data. The original code suffered from
this, and I cannot see a good reason to carry it over. Better folk
than I have commented that it generally indicates bad design, and I
see no reason to disagree.</p>
<p>Specifically, if <tt class="classname">Book</tt>'s data were
made private, <tt class="classname">ChildBook</tt> would not have
direct access to it. <tt class="classname">Book</tt>, however,
provides accessor functions to its data. Whether knowingly or
unknowingly, the author correctly made these accessors non-virtual.
This represents what Scott Meyers (<a href=
"#Meyers1996">Meyers1996</a>) calls an &quot;invariant over
specialization&quot;, something which a derived class can use in the
base, but cannot change how it is implemented.</p>
<p><tt class="classname">ChildBook</tt>, then, does not have these
same data members, relying instead on the base class to correctly
implement these common data items (<tt class="varname">author</tt>,
<tt class="varname">title</tt> and <tt class="varname">price</tt>).
However, it implements <tt class="varname">reading_age</tt>, and so
should provide copy construction and assignment. With no inherited
data, this would take the following form:</p>
<pre class="programlisting">
ChildBook::ChildBook (const ChildBook &amp; rhs)
    : Book (rhs), reading_age (rhs.reading_age)
      { /* empty constructor */ }
</pre>
<p>This works because a <tt class="classname">ChildBook</tt> can be
implicitly converted to a <tt class="classname">Book</tt>. There is
no need for the base class to allow for a converting copy
constructor for every base class (a maintenance nightmare) because
of this.</p>
<p>Correspondingly, <tt class="classname">ChildBook</tt> has no
accessors for data members present only in the base class, but the
following will still be valid, calling the base class function:</p>
<pre class="programlisting">
ChildBook book;
book.name();
</pre>
<p>We have now removed all inherited items from <tt class=
"classname">Book</tt>! Ah well, at least we can put one other
virtual function in. I have seen this idiom, and used it, but I
cannot remember the reference (apologies if you are the author). At
the moment, both <tt class="classname">Book</tt> and <tt class=
"classname">ChildBook</tt> define separate stream output functions.
We can factor this so that just one <tt class=
"methodname">operator&lt;&lt;()</tt> calls a virtual function on a
<tt class="classname">Book</tt> reference argument. <tt class=
"classname">Book</tt> defines a (virtual) <tt class=
"methodname">print()</tt> function, which is over-ridden in
<tt class="classname">ChildBook</tt>.</p>
<pre class="programlisting">
class Book {
public:
    virtual void print(ostream &amp; os) const 
            { os &lt;&lt; title &lt;&lt; author &lt;&lt; price; }
};
class ChildBook : public Book {
public:
    virtual void print(ostream &amp; os) const 
        { Book::print(os); os &lt;&lt; reading_age; }
};
ostream &amp; operator&lt;&lt;(ostream &amp; os, 
                                        const Book &amp; rhs){
    rhs.print(os);
    return os;
}
</pre>
<p>This relies on the fact that references, as well as pointers,
are polymorphic in their behaviour. It means also that <tt class=
"methodname">operator&lt;&lt;()</tt> does not have to be a friend
function. Note: this isn't really an error in the original code; I
add it here hoping that any readers not familiar with this will
find it useful.</p>
<p>The accessor functions in <tt class="classname">Book</tt>
should, of course, be const functions, and the cast to <tt class=
"type">const char const*</tt> is unnecessary, as this conversion
takes place automatically for the returned pointer. I think that
the need for explicit &quot;setter&quot; functions is doubtful, especially
since a full constructor and a copy constructor are both provided.
After all, few books change either title or author in their
lifetime. If they stay, the arguments should be const, and, as with
copy assignment, they suffer from release before copy.</p>
<p>I also question the use of a double to store the price of a
book. Quite apart from the magnitude available (there may be books
that cost that much but I wouldn't be able to buy one of them)
there are issues of accuracy and comparison. Floating-point values
have a certain notoriety about them in terms of accuracy of
comparison, such as should these values compare equal?</p>
<p>100.01</p>
<p>100.010000000000001</p>
<p>As it happens, we only need accuracy to two decimal places, and
storage in an unsigned would probably make more sense, and be more
efficient into the bargain. For output purposes, a simple division
by 100 is all that is needed.</p>
<p>The <tt class="classname">ChildBook</tt> class has one other
feature that I promised to return to earlier: a constructor with
default arguments. In this case all the arguments are defaulted.
There are four of them, which means this is a five in one
constructor. What is more serious is the fact that, under some
circumstances, a <tt class="type">char*</tt> can be implicitly
converted to a <tt class="classname">ChildBook</tt>. Here is one
such circumstance:</p>
<pre class="programlisting">
void some_function (ChildBook b) { }
char * s = &quot;Hello, World&quot;;
some_function (s);
</pre>
<p>This may be contrived, but it illustrates the point. In the
absence of keyword explicit, this can be avoided by having separate
constructors for each possibility. In the case of <tt class=
"classname">Book</tt>, the base class, the default constructor
created a &quot;default&quot; <tt class="classname">Book</tt> (naturally),
and a single constructor for all data types was given. Having made
changes already mentioned regarding data members, <tt class=
"classname">ChildBook</tt> is left with only a single data member
anyway, so we can only remove the problem of implicit conversion
with a dummy argument:</p>
<pre class="programlisting">
ChildBook::ChildBook (double your_reading_age, int dummy) : reading_age (your_reading_age) { }
</pre>
<p>As with <tt class="varname">Book::price</tt>, using a <tt class=
"type">double</tt> for <tt class="varname">reading_age</tt> is
suspect.</p>
<p>The only other point I would make is for the sake of
readability. <tt class="classname">ChildBook</tt> should really
define a destructor. As it happens one is not required, and the
(now virtual) destructor for <tt class="classname">Book</tt> does
all the work, but I believe this might be a source of future error.
My preference is to explicitly label it <tt class=
"type">virtual</tt>.</p>
<p><tt class="classname">BookList</tt> suffers from two problems.
Firstly it derives from the common base class, <tt class=
"classname">BookBase</tt>, which indicates that both a <tt class=
"classname">BookList</tt> and a <tt class="classname">Book</tt>
have things in common. In this case, they do not (although they
might, if <tt class="classname">BookList</tt> were some kind of
index, for example), so a public inheritance relationship is not
the right thing here. Secondly, <tt class="classname">BookList</tt>
is a container of concrete types. If <tt class=
"classname">ChildBook</tt>s were added to this list, they would be
&quot;sliced&quot;, becoming mere <tt class="classname">Book</tt>s instead,
completely losing the <tt class="varname">reading_age</tt>
information. This is because each item added to the list would be
copied using <tt class="classname">Book</tt>'s copy constructor,
which takes a <tt class="classname">Book</tt> reference. In order
for the list to contain multiple types, it would have to contain
<tt class="type">BookBase*</tt>s (or <tt class="type">Book*</tt>s),
but this suffers from different problems.</p>
<p>Such a list of <tt class="classname">BookBase</tt>s makes no
distinction between a <tt class="classname">BookBase</tt>,
<tt class="classname">Book</tt>, <tt class=
"classname">ChildBook</tt> and <tt class="classname">BookList</tt>.
This list could contain a mixture of these three types of &quot;thing&quot;,
with no way of distinguishing the concrete type of each without
resorting to RTTI (which itself relies on polymorphism, which is
missing from <tt class="classname">Bookbase</tt>) hackery, because
<tt class="classname">BookBase</tt> itself allows no operations and
has no data. Even if the list were of <tt class=
"classname">Book</tt> type, allowing <tt class=
"classname">Book</tt>s and <tt class="classname">ChildBook</tt>s, a
cast would have to be made from <tt class="classname">Book</tt> to
<tt class="classname">ChildBook</tt> to access the <tt class=
"varname">reading_age</tt> of the item, but if the item were not a
<tt class="classname">ChildBook</tt> at all, merely a <tt class=
"classname">Book</tt>, the conversion would fail.</p>
<p>If the collection were to be treated as if all of them were
<tt class="classname">Book</tt>s, we would not have a problem here;
the list might only be used to provide the titles and authors in
the collection. This use would be perfectly valid in that case,
although not necessarily moral.</p>
<p>Making the <tt class="methodname">operator&lt;&lt;()</tt> a
<tt class="type">friend</tt> is superfluous in this case, as the
list data member is already public. More to the point, since there
is only one public data item, and no member functions, the need for
<tt class="classname">BookList</tt> at all is superfluous, and the
same effect could be achieved with a typedef.</p>
<p>I think that the relationship between <tt class=
"classname">Book</tt> and <tt class="classname">ChildBook</tt> is
valid, and useful. On reflection, a common base class for them is
not needed, and, even as a concrete type, <tt class=
"classname">Book</tt> makes a sensible base class, reflecting as it
does the common elements needed for <tt class=
"classname">ChildBook</tt>s and maybe <tt class=
"classname">ComicBook</tt>s, <tt class="classname">TextBook</tt>s,
and so on.</p>
<p>As already commented by Francis, a compiler with no <tt class=
"type">string</tt> value type is poor indeed. For the purposes to
which <tt class="type">char*</tt> is put in this code, it would be
worth composing a simple string class to handle lifetime and
assignment issues. I think an outline for such a class has appeared
in 90% of the C++ text books I have read (good and bad) so I'll not
outline one here.</p>
<p>Finally, printing details of each book in the list. The for_each
thingy you mention goes something like this:</p>
<pre class="programlisting">
typedef list&lt;Book&gt; BookList;
struct print {
    print (ostream &amp; os) : strm (os) { }
    void operator() (const Book &amp; rhs) 
                                        { rhs.print(strm); }
    ostream &amp; strm;
};
ostream &amp; operator&lt;&lt; (ostream &amp; os, const BookList &amp; b) {
    for_each (b.begin(), b.end(), print (cout));
    return os;
}
</pre>
<p>The print structure is called a <span class=
"emphasis"><em>function object</em></span>, or <span class=
"emphasis"><em>functor</em></span>. Briefly this is so due to the
operator() member function. For a fuller description, check
Stroustrup's &quot;<i class="citetitle">C++ Programming Language</i>&quot;
(<a href="#Stroustrup2000">Stroustrup2000</a>).</p>
<p>I sincerely hope this is useful to you, and other readers. All
the best with your degree.</p>
<p>[<i><span class="remark">The complete article and code is
available on our web site. FG</span></i>]</p>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e753" id="d0e753"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Henney2000" id="Henney2000"></a>
<p class="bibliomixed">[Henney2000] Henney, Kevlin, &quot;<span class=
"citetitle"><i class="citetitle">Source Cohesion &amp;
Decoupling</i></span>&quot;, Overload 39</p>
</div>
<div class="bibliomixed"><a name="Henney1998" id="Henney1998"></a>
<p class="bibliomixed">[Henney1998] Henney, Kevlin, &quot;<span class=
"citetitle"><i class="citetitle">Creating Stable
Assignments</i></span>&quot;, C++ Report</p>
</div>
<div class="bibliomixed"><a name="Meyers1996" id="Meyers1996"></a>
<p class="bibliomixed">[Meyers1996] Meyers, Scott, &quot;<span class=
"citetitle"><i class="citetitle">More Effective C++</i></span>&quot;,
Addison Wesley Longman</p>
</div>
<div class="bibliomixed"><a name="Stroustrup2000" id=
"Stroustrup2000"></a>
<p class="bibliomixed">[Stroustrup2000] Stroustrup, Bjarne,
&quot;<span class="citetitle"><i class="citetitle">The C++ Programming
Language, Special Edition</i></span>&quot;, Addison Wesley</p>
</div>
</div>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e776" id="d0e776"></a>Competition
No 7</h2>
</div>
<p><span class="bold"><b>Set by Francis Glassborow</b></span></p>
<p><span class="bold"><b>Entries by January 7th</b></span></p>
<p>To a large extent, I use what I can lay my hands on when looking
for material for this competition. I know we have had rather a lot
of C++ recently, and we have never had any Java (if the Java
Section editor's like to set one, or invent their own competition,
I would be happy to support it) so this time here is a short
program in C.</p>
<p>This piece of code was recently posted to comp.lang.c.moderated
with a request for help. The author claims two weeks experience of
C. The intention of the program is to remove whitespace from the
start and end of lines. Now, review the code and try to explain the
problems in the context of helping a raw novice.</p>
<pre class="programlisting">
#include &lt;stdio.h&gt;
#define MAX 1000
int rtrim(char s[]);
int ltrim(char s[]);
char s[MAX];
main() {
    int j;
    while((j = getline(s, MAX)) &gt; 0) {
        rtrim(s);
    }
    ltrim(s);
}
int rtrim(char s[]) {
    int i;
    int j = getline(s , MAX);
/*j-2 because the last two array values are null and \n*/
    for (i = j - 2; s[i] == ' ' || s[i] == '\t'; i--) {
        s[i] = '\0';
    }
    return 0;
}
int ltrim(char s[]) {
    int i;
    for(i = 0; s[i] != '\0' ; i++) {
        if(s[i] == ' ' || s[i] == 't')
        s[i+1] = s[i];
    }
    return 0;
}
/* This method will fill the array with each new line */
int getline (char s[], int lim) {
    int c, i;
    static char s[MAX];
    for (i = 0; i&lt;lim-1 &amp;&amp; (c = getchar()) !=EOF
                                  &amp;&amp; c != '\n'; ++i) {
        s[i] = c;
    }
    if (c == '\n') {
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i;
}
</pre></div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
