    <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  :: A Delphic Experience</title>
        <link>https://members.accu.org/index.php/articles/565</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #29 - Dec 1998</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

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

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

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

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

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

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

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

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

                    -                        <a href="https://members.accu.org/index.php/articles/c65+199/">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;A Delphic Experience</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 27 December 1999 17:23:22 +00:00 or Mon, 27 December 1999 17:23:22 +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></h2>
</div>
<p>I always label myself as a C++ programmer, which is odd as I've
mainly been using Borland's Delphi for the last two and a half
years. This article relates to my experiences during that time.</p>
<p>So why am I writing about a proprietary version of Pascal in a
C++ publication?</p>
<p>Two reasons. Firstly, because the editor seemed short of
material, so I thought I could get away with it and secondly,
because I'm really interested in how the differences between the
languages lead to different solutions to similar problems.</p>
<p>Now, if you've survived so far and you're not familiar with
Delphi, here's a quick overview. You never know when it may be
useful, if only to say &quot;I'm not doing it in Delphi
because&hellip;&quot;</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e28" id="d0e28"></a>Delphi and
Object Pascal</h2>
</div>
<p>The greatest strength and weakness of Delphi are the same thing.
It is a proprietary language that is targeted at just one platform
- Windows. Borland were free to do what they liked to extend the
Pascal syntax on which it is based. At the same time, they created
a class library called the VCL that provides components both for
the user interface and for database access. The environment is a
very effective RAD in that it allows you to build both the user
interface and database access parts of your application with very
little code being needed. In that respect, it is in competition
with MS Visual Basic. For this reason, as well as the fact the
Borland seemed to market Delphi as a database application builder,
Delphi isn't always recognised as a general applications language -
albeit in the context of Windows only.</p>
<p>Prior to Delphi, Borland extended their Pascal to include
objects. This extension was rather like the class in C++ as opposed
to the 'struct' in C. The 'object' type extends the 'record' type
by allowing member functions, constructors etc. These types can be
instantiated on the heap, the stack or statically.</p>
<p>Delphi turns its back on this extension! Instead, a new keyword
'class' was introduced. All classes are subclasses of 'TObject'.
Such classes can only be instantiated on the heap. Source code
normally uses references to these objects. These references are
assignable; i.e. they're more like references in Java - in other
words pointers. Class members are accessed using the dot
operator.</p>
<p>One big downside to this scheme is that you must explicitly
create and free your objects. You don't get the benefits of scope
based lifetimes within your methods. In fact, Object Pascal is
generally more verbose than C++.</p>
<p>The first version of Delphi was 16 bit only; all three
subsequent versions are 32 bit only. Each new version has extended
the language and the VCL substantially. A quick summary of the
current feature set goes something like this:</p>
<p>Run time type information is always available for class
instances.</p>
<p>Class references. That is, references to a class type rather
than an instance. These may be used with virtual constructors, a
feature completely missing from C++.</p>
<p>Exception handling with the 'try-catch' construct is broadly
like that of C++ except that only class instances can be thrown and
though the stack is unwound, it doesn't necessarily help. As
compensation, a 'try-finally' construct allows you to roll your own
recovery.</p>
<p>Classes may have properties that may be assigned to and from.
The nice thing about this is that they can be implemented by direct
access to a private data member or by 'set' and 'get' methods.</p>
<p>As well as procedural types, i.e. function pointers in C++,
there are method pointers, In C++ terms; these are a package of
pointer to a method plus a pointer to the object. These are widely
used in the VCL for event handling, e.g. 'button clicked' or 'edit
change' events.</p>
<p>Language level support for OLE Automation through variants of
dispatch type.</p>
<p>COM interface declarations, usage and implementation. This means
that you may implement any number of interfaces in your classes.
That's a sort of multiple interface only inheritance in the same
way as Java. Also, dual interface COM objects can be used
efficiently. Interfaces when used as references to external COM
objects or internal Delphi class instances do have scope based
lifetimes, i.e. they behave like C++ smart COM pointers.</p>
<p>There are some significant missing features. Particularly:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>No proper multiple inheritance. To Java enthusiasts I gather
that this is a virtue!</p>
</li>
<li>
<p>No operator overloading.</p>
</li>
<li>
<p>No macros, though there is conditional compilation.</p>
</li>
</ul>
</div>
<p>Because of the nature of Pascal and the fact that types aren't
included in headers but instead are declared in an interface
section, there can be problems with circular references. If two
classes have a two-way association, they must be declared in the
same unit or you must jump through hoops involving either
inheritance or type casting.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e69" id="d0e69"></a>Effects on
programming style</h2>
</div>
<p>This is the real meat of this article. Some of the differences
between C++, Java and Delphi must be apparent by now. The
differences in syntax are neither here nor there in the main. Types
are declared in type sections and instances are created in their
own peculiar way. If you follow the rule that everything is back to
front, wherever you have a space put a colon, put semicolons
wherever there's room except before an 'end', you'll probably have
compilable code!</p>
<p>On the other hand, certain C++ idioms and techniques just aren't
available. You have to live without the STL. You can't create a
locking object and let its scope define the lock on a resource.
Well, you can if you don't mind using an interface rather than a
class reference and you can wait until the end of the method.</p>
<p>At the detailed level, Pascal programmers use language features
such as sets, arrays with unusual indexes and so on that are less
freely used in C++. Most such things are perfectly possible now,
either with class libraries such as STL or by rolling your own with
operator overloading etc. It's largely a matter of habit. For
example, I still find myself doing low level bit masking to pack
all kinds of stuff into an integer or whatever, just like we did
years ago.</p>
<p>Finally, source files are usually longer with more classes
declared in one file because of the circular reference problem, The
first significant feature that I want to discuss is really a
mundane one but it's nevertheless pervasive in its scope.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e80" id="d0e80"></a>Properties</h2>
</div>
<p>Generally speaking, Delphi programmers don't have long and
bitter disputes over how to do accessors and mutators. While we're
on the subject, I utterly detest the naming of methods like
GetColour(). The prefix 'Get' should be reserved for the cases when
it really does cost something, like
GetThatPileOfMachineryRustingInTheCorner(). But I digress and lose
my last two surviving readers on religious grounds.</p>
<p>The great thing with properties is that you can define your
attributes in a simple way initially. If you want a property to be
readable and writeable, there's nothing to stop you simply
declaring the data member publicly with the name that the outside
world will see if you want to! Not that I would of course, the
point is that property access is semantically identical to data
member access, so you can always leave your options open. The
stages of complexity that you could go through are:</p>
<pre class="programlisting">
property Colour : TColor read fColor write fColor;
</pre>
<p>or</p>
<pre class="programlisting">
Colour : TColor;
</pre>
<p>The above are effectively equivalent.</p>
<pre class="programlisting">
property Colour : TColor read fColor write SetColor;
</pre>
<p>This would be appropriate if you wanted to do something when the
colour changes e.g. invalidate the window.</p>
<pre class="programlisting">
property Colour : TColor read GetColor write SetColor;
</pre>
<p>This would allow you to delegate the colour storage to some
other object when you completely re-implement the class.</p>
<p>Incidentally, properties may also take any number of indexes of
any type and may also be declared as default indexed properties.
This gives an effect similar to the overloaded [] operator in
C++.</p>
<p>So in the end, properties are perhaps a syntactic sugar in much
the same way as operator overloading. They don't have an enormous
impact on the grand design of a program but they make the details
of class declaration and usage much cleaner.</p>
<p>I assume that they won't make inroads into the C++ language as
such. Nevertheless, Borland has property extensions to C++ Builder
as well as their being generally used in COM.</p>
<p>It's also worth contrasting this with the Data Attribute
Notation style introduced in Overload 28. As that article is the
first I've heard of it and it seems to serve a slightly different
purpose, I'll leave it as an exercise for the reader. One
interesting point is that DAN requires class types for each
attribute, something that's not needed in our context. This is a
difference that will crop up again, so file it away for now!</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e111" id="d0e111"></a>Dynamic
Construction</h2>
</div>
<p>Having class references and virtual constructors allows you to
achieve something like class factories with no programming
overhead! I have used this feature many times and it is something
that C++ really misses. Look at the horrors of CRuntimeClass and
the macros that use it in the old MFC library and you'll know what
I mean.</p>
<p>However, I'd like to sketch another case where it was
useful.</p>
<p>I needed a red-black tree implementation that could be used as a
basis for mapping classes. These trees are so useful that we needed
to get a good design so that we could take full advantage. There
are many possible ways that a tree could be made to work. For
example, the key and the value could be stored in one object that
is collected by the tree. The comparison function might then take a
reference to two objects. This is all right for inserting objects
into the tree but less useful for lookups, where a similarly keyed
object would need to be created temporarily. In the case of a map,
the key probably won't be part of the collected object at all.
Also, who is to say that it's just objects that you want to
collect?</p>
<p>The STL approach would be the ideal but of course is out of the
question. The trick here is to write the tree code so that instead
of creating nodes of a fixed type, the actual node type can be
given when the tree is created. The node type must of course be
derived from a class that has the left and right references and the
node colour. In addition, it might carry a string key and an object
reference, or just an object reference or string key and string
value. Because a class reference is passed to the tree and a
virtual constructor is available, nodes of the correct type are
created. For this purpose, a factory class instance would need to
be passed in C++, and although there is more coding involved, it
may well be a useful technique to consider.</p>
<p>Of course, the down side in Delphi is that you need to write all
these derived node classes yourself and that a certain amount of
casting is required. The casting can largely be eliminated from
client code however.</p>
<p>The upshot is that I was easily able to create the half dozen
basic map classes that I needed as well as use the tree as an
ordered collection.</p>
<p>Before I go on with the red-black tree story, there are other
uses to which dynamic construction may be put. With a collection of
objects derived from some common base type, it is often necessary
to clone these objects. Because each instance has its class type
available through the RTTI mechanism, most of the work can be done
in the base class. A base clone method can create the correct type
and then call a virtual assign method. Each derived class need only
implement an assign method.</p>
<p>Another frequent use is in object persistence. When reading a
stream, a class identifier of some kind is extracted and mapped to
a class reference. This reference is then used to directly create
the streamed object. A familiar mechanism in C++, except factory
objects replace the class references.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e130" id="d0e130"></a>Events</h2>
</div>
<p>What about the comparison methods that the red-black tree needs
in order to operate? Clearly a plain function pointer isn't going
to be of much use. Its parameters are hard to pin down. One
parameter could reasonably be the red-black node but another
parameter would need to be the key. Unfortunately, the key is of
unknown type - perhaps not a problem if you have templates. One
workable solution is to have a base class that has a virtual method
that takes the node and whose state includes the key or at least
provides access to the key. Although this kind of solution is
valid, it does lead to additional class types being declared and
probably leads to additional instances that you could well live
without.</p>
<p>The Delphi solution is a variant on the latter approach, instead
of providing an instance of a class, provide an 'event' in the form
of a method pointer. Now we are placing no constraints on the type
of the object that does the work, we know only that it has a method
with the right signature and that it can obtain a key from
somewhere.</p>
<p>In the case of a map class, the event handler may be a method of
the map class itself. Indeed, I created a hierarchy of maps that
were based on the key type, so that each could handle the key in
the most appropriate way. For each of these I also derived a node
class that had a suitable key. From these maps and nodes I then
derived the specific classes that mapped the type I needed. This
may sound like it was a lot of work but it wasn't so bad. By
splitting the type problem into key and value stages, the amount of
source code needed was very small. Not as small as it would have
been with templates but at least the amount of compiled code was
probably very similar, if not less!</p>
<p>The above example is one of many where this mechanism has been
used in a context other than user interface programming. One
significant way that these approaches differ from the generic
approach is that the red-black tree code only needs to be compiled
once, it isn't compiled repeatedly for each type that is
needed.</p>
<p>The main difference with the traditional object oriented
approach is that we don't have to introduce base classes that are
likely to be inconvenient when we've moved on from this library.
This inconvenience becomes apparent when you find yourself either
creating over complex derived instances that need to reference
other classes (such as a map class). These classes may need to
access state in another class that you really didn't want to
expose. In this case, the best solution would probably be to
instantiate one of the classes as a short-lived instance with a
copy of the key as part of its state.</p>
<p>What I'm trying to say is that the event mechanism as used by
Delphi provides an alternative form of polymorphism. Rather than an
instance presenting an interface defined in its base class, it is
simply presenting a method of the required type. In many cases,
this saves you needing to create class hierarchies when none would
otherwise be needed. This is analogous to the advantage of generic
programming using templates where for example, you're not forcing
collected objects to be of a 'collectable' class. In practice of
course, Delphi programs still rely heavily on conventional object
oriented class hierarchies, just as templates can't replace them in
C++.</p>
<p>It's worth looking a little more at the conventions for
implementing events. Typically, event methods are procedures rather
than functions, even when the handler may pass data back to the
caller. That is because in most cases, the absence if a handler
allows the default behaviour. Rather than relying on a return
value, a non-const reference to a value that is already set to the
default state is provided as a parameter. Often, you might want to
achieve the specialisation either by providing an event handler or
by derivation. In this case, the code that calls the event is
provided as the body of a virtual method. For components this is
very natural. For example, if you were sub-classing an edit control
and you needed to extend the 'OnChange' event, you would simply
override the 'Change' method, leaving the OnChange property
available as it is with the base class.</p>
<p>The good news is that not only is this article nearing the end
but that this mechanism is available to the C++ programmer as well.
See my article in Overload 17/18 for an example that uses a
template to package an object pointer and method pointer of the
target type. This implementation is more involved simply because of
the need to support multiple inheritance. With single inheritance
and casting, the job can be done in the same way as in Delphi.</p>
<p>Bad news for Java programmers though. As the language doesn't
support method pointers, you will have to use pure OO techniques
only.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e151" id="d0e151"></a>A final note
on events</h2>
</div>
<p>COM uses a different model for the same purpose - connection
points. This entails providing an interface to handle a number of
events rather than just the one method. This can be inefficient if
you're only interested in a subset of events fired by an out of
process server. One good feature of this mechanism is that multiple
interfaces can be advised side by side, i.e. more than one object
can be notified when an event occurs. This feature can be
reproduced in Delphi but you have to do a bit more work. An event
property has to be implemented as an event list! I have found this
to be a very useful thing in terms of co-ordinating objects,
particularly in user interfaces. I have also put the event lists
into an 'event broker' collection that has been even more
useful.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
