    <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  :: operator == ()</title>
        <link>https://members.accu.org/index.php/articles/577</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;operator == ()</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 27 December 1999 17:23:23 +00:00 or Mon, 27 December 1999 17:23:23 +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>Sometime ago there was an article in C++ Report on the subject
of writing your own <tt class="methodname">operator=()</tt>.
Despite the considerable efforts of the author there were still
faults in his proposals. The reason that I mention that is that I
expect there to be some flaws in this article as well. Please find
them and send them in. That way we will all be wiser. Indeed I will
be most disappointed if none of you have anything to add to this
article. The biggest reward I get for writing for publication is
the amount I learn from my mistakes.</p>
<p>Obviously I like to be right and it gives me a warm feeling when
others adopt some idea of mine (particularly if they are more
expert than I am) but the profit comes from learning something
new.</p>
<p>The first decision that any class designer has to make with
regard to <tt class="methodname">operator=()</tt> is what semantics
are appropriate to the type in question. The following
possibilities spring to mind:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Unique Objects - a bit like Java's objects</p>
</li>
<li>
<p>Pure value types - no inheritance anticipated.</p>
</li>
<li>
<p>Polymorphic types</p>
</li>
<li>
<p>With potential ordering across subtypes</p>
</li>
<li>
<p>Without ordering between subtypes.</p>
</li>
</ul>
</div>
<p>Let me tackle these in ascending order of difficulty.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e50" id="d0e50"></a>Unique Objects:
Is It the Same Object</h2>
</div>
<p>This one is very easy. Check the following code:</p>
<pre class="programlisting">
class Unique
{
public:
 bool operator==(Unique const volatile &amp;)
 const volatile throw();
 // rest of interfaces
};

inline bool Unique::operator ==
  (Unique const  volatile &amp; rhs) 
         const volatile throw()
{
  return (this == &amp;rhs) ? true : false;
}
</pre>
<p>The idea here is that the meaning of identity is that they are
the same object. At first sight you may wonder if such a strong
definition of identity has any utility. If there were no
possibility of aliasing (referencing) the answer would be 'no' but
with objects being passed around by reference there may be times
when you want to determine if two references to instances of a
<tt class="classname">Unique</tt> actually refer to the same
instance.</p>
<p>As I was writing this an errant thought crossed my mind, objects
that possess this characteristic (identity means the same object)
are inherently unordered when it comes to various Standard Library
features that handle collections of objects. Yet, some STL features
require an ordering. I wonder if this would be good enough?</p>
<pre class="programlisting">
inline int Unique::compare
  (Unique const volatile &amp; rhs) 
    const volatile throw()
{
  return (*this == rhs) ? 0 : 1;
}

inline bool Unique::operator &lt; 
  (Unique const volatile &amp; rhs) 
   const volatile throw(
{
  return compare(rhs) ? true : false;
}
</pre>
<p>I think that needs rather more thought than I currently have
time for (the copy date for this issue of Overload was seven days
ago :-( ) so it is a chance for you to do the thinking and share
the results with the rest of us.</p>
<p>The only problem with <tt class="methodname">operator==()</tt>
in this case is ensuring that the prototype is correct. There is no
problem with derived types because two identifiers can only refer
to the same address if the objects are the same (and therefore have
the same dynamic type as well). This means that there would seem to
be no problem with making <tt class="methodname">operator==()</tt>
a member function. The only caveat is that you might have problems
if you elected to provide some other meaning for <tt class=
"methodname">operator==()</tt> when applied to objects of different
derived types. However, I would suggest that any design that
supported such a bizarre concept would belong in a fantasy
nightmare world.</p>
<p>So how about the inclusion of <tt class="literal">volatile</tt>?
The simple question is 'Why not?' There can be a hidden cost to
gratuitous usage of <tt class="literal">volatile</tt> (it disables
many potential optimisations) but in the instances above the
objects are never accessed and so making the implementation as
broad as possible should not incur a cost.</p>
<p>A similar argument supports the addition of a <tt class=
"function">throw()</tt> exception specification. All the functions
above are leaf functions or functions forwarding to leaf functions.
If an exception gets raised inside this code you have a serious
problem.</p>
<p>Again, I think these functions are simple enough to justify
inlining, but perhaps you disagree. If so please share your
reasons.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e94" id="d0e94"></a>A Pure Value
Type: Do They Have the Same Value?</h2>
</div>
<p>This is not quite as simple as it may seem. We have to ask
ourselves what it might mean if someone compared an instance of a
derived type with an instance of our type. Of course you have not
prepared your pure value type for derivation, but that does not
mean that someone will not do it one day. What do you want to do in
such a case? There seem to be two choices:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Compare the base subobject of the instances</p>
</li>
<li>
<p>Check that you are not comparing derived instances</p>
</li>
</ul>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e106" id="d0e106"></a>Compare
Anyway</h2>
</div>
<pre class="programlisting">
class PureValue 
{
public:
  int compare(PureValue const &amp;) const;
  // rest of interfaces
};

inline bool operator == 
  (PureValue lhs, PureValue rhs)
{
  return lhs.compare(rhs) ? false : true;
}
</pre>
<p>Note the differences between this and the unique object case. I
have removed the use of volatile because I can no longer get that
for free (if I need a volatile case I will need to provide that as
a separate function. Actually this seems unlikely.)</p>
<p>When deciding on the low-level design of PureValue you will need
to decide whether you are going to pass it around by value or by
reference. Only the class designer can know which is better suited
to the type being implemented. Of course the way C++ works makes
this purely a decision for the class designer. You may think that
pass by (const) reference will normally be the way to go but I
think this is less obvious than sometimes imagined. Even with the
const qualification pass by reference inhibits many desirable
optimisations and in the case of multi-threaded code pass by
reference has some bad implications. Suppose that some other thread
has access to that variable (as a class designer you do not know
this will not happen) even though you passed by const &amp; the
object might be changed by another thread. Much safer to pass by
value and write a copy constructor that locks the instance during
copying. (This is another entry point for the thoughtful reader to
contribute an article).</p>
<p>Once I decide that I will pass the right-hand operand by value,
symmetry suggests that I should handle the left-hand operand the
same way. That more or less requires a non-member operator==().
However note that there is no cause for using friend. The compare()
member function seems a much better way to go. It is useful for
other things as well. Exactly how you implement
PureValue::compare() will depend on the details of PureValue.
However I think the const &amp; parameter is probably correct this
time. The other parameter (this) is being passed as a pointer and
you have no choice. If you intend calling PureValue::compare()
direct from code that needs to be thread safe you will need to take
suitable action at the call site.</p>
<p>What about inlining operator==()? Well why do you think I chose
not to? And what happened to the exception specifications? I didn't
just get lazy. Think about it.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e119" id="d0e119"></a>Only Compare
Base Objects</h2>
</div>
<p>Suppose that we want to prevent comparisons between base
instances and derived instances and we want to 'force' derived
classes to do their own work. Now we need a utility to detect
breaches of this design constraint. Ideally we would like to detect
this problem at compile time. To be honest, I cannot think of any
way to do that (cue for another contribution&#9786;). However, the
following will manage it at runtime:</p>
<pre class="programlisting">
class NoDerive 
{
public:
  bool notDerived() const;
  int compare(NoDerive const &amp;) const;
  // rest of interfaces
};

bool NoDerive::notDerived() const 
{
return typeid(*this) == typeid(NoDerive);
}

int NoDerive::compare
  (NoDerive const &amp; rhs) const
{
  if (!(notDerived() &amp;&amp; 
     rhs.notDerived()))
     throw IllegalComparison();
  // normal code
}

bool operator==
  (NoDerive const &amp; lhs, 
   NoDerive const  &amp; rhs) 
{
  return lhs.compare(rhs) ? false : true;
}
</pre>
<p>The <tt class="methodname">NoDerive::notDerived()</tt> member
function relies on being able to determine the dynamic type of the
instance. For this reason all parameters must be passed by
(<tt class="literal">const</tt>) reference or as pointers. If it
matters this means that the normal code in <tt class=
"methodname">NoDerive::compare()</tt> will need to lock the
parameters while they are being accessed. It might be worth
considering starting the code by copying the parameters to local
variables. By the way you should not get into the habit of thinking
that multi-threaded code will be run on a single processor. There
are many things that would be safe under such a condition that
become disastrous when using multiple processors (something that
will become increasingly common in future years).</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e137" id="d0e137"></a>Comparison of
Instances of Polymorphic Types</h2>
</div>
<p>Again we must consider what we want. Think about Chess pieces.
These are a fairly good example of a simple polymorphic type
(actually we have an interesting complication because pawns can
promote, but we will leave that for another article in a different
context). Each Chess piece has its own properties. Some of those
are fixed by its fundamental type (legal moves, colour etc) other
things vary during a game (position, value to the player - captured
pieces have no value, rooks on open files have enhanced value -
etc.) Because each side has pairs of rooks, knights etc. we can
reasonable ask two questions:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Are two pieces the same type?</p>
</li>
<li>
<p>Do they belong to the same side?</p>
</li>
</ul>
</div>
<p>The second question does not seem to lend itself to the identity
operator as well as the first. My sense is that the second question
should be relegated to a member function. Or even to comparing the
return value of a member function <tt class=
"methodname">Colour::whatColour()</tt>.</p>
<p>Let us look at a draft for a base class for a hierarchy of Chess
pieces.</p>
<pre class="programlisting">
class ChessPiece 
{
public:
  enum Colour {unknown, black, white};
  Colour whatColour();
  bool sameType(ChessPiece const &amp;)const;
  int compare(ChessPiece const &amp;)const;
  virtual ~ChessPiece() = 0;
  virtual void move();
private:
  Colour col;
  Position pos;
};
</pre>
<p>This is far from a complete design, but it will do for a start.
Note that functions such as <tt class="methodname">compare</tt>
must be in the base class, whereas functions such as <tt class=
"methodname">move()</tt> must be implemented in the relevant
derived class (<tt class="classname">Pawn</tt>, <tt class=
"classname">King</tt> etc) Oddly, in this case we probably would
not use <tt class="methodname">compare()</tt> to provide an
implementation of <tt class="methodname">operator ==()</tt>. This
will meet our needs perfectly well:</p>
<pre class="programlisting">
bool operator == 
  (ChessPiece const &amp; lhs, 
   ChessPiece const &amp; rhs) 
{
  return lhs.sameType(rhs);
}
</pre>
<p>and the implementation of <tt class=
"methodname">ChessPiece::sameType()</tt> could be something such
as:</p>
<pre class="programlisting">
bool ChessPiece::sameType
  (ChessPiece const &amp; rhs)const 
{
  return typeid(*this) == typeid(rhs);
}
</pre>
<p>While Chess pieces are a good simple example of a flat hierarchy
many other hierarchies have considerable depth. The first issue we
must face is that if we are to avoid comparing things of different
derived types we must provide base class functionality. An ABC with
only an interface is not good enough. Using ABC's as equivalent to
Java interfaces is fine but we can do more with ours and sometimes
that works to our advantage.</p>
<p>As I am running a bit short of time I am simply going to offer
you the sample code at the end of this article which I wrote for a
discussion in <tt class="literal">comp.lang.c++</tt>. Note that the
following code is simply to illustrate a principle. But, feel free
to rip it to shreds. The unusual returns in <tt class=
"methodname">compareInstances</tt> simply allow some simple test of
concept code.</p>
<p>For testing purposes identity has been treated as 'same object'.
In real code do something else.</p>
<p>This design detects attempts to compare derived objects for
which no class specific comparison has been provided Unfortunately
this is at run time. Any ideas as how to move that forward to
compile or link time would be gratefully received.</p>
<p>I would also like to hear of any ideas as to how to force all
derived classes to implement a particular function. Pure virtuals
are not strong enough as the requirement is satisfied as soon as a
derived class provides an implementation. What I want is a way to
require diagnosis of the use of any derived class that does not
provide its own implementation of a pure virtual in the base class.
I considered using a virtual base class on the grounds that it is
the most derived class that constructs it, but a few moments of
thought convinced me that that would not work. Anyone got any
ideas?</p>
<pre class="programlisting">
#include &lt;iostream&gt;
#include &lt;typeinfo&gt;

//introduce namespace std
using std::typeid;
using std::cout;

class Base 
{
  virtual int compareInstances
   (Base const &amp; rhs)const 
 {
    if(typeid(Base) != typeid(*this))
     return 99;
    return (&amp;rhs == this)? 0 : 3;
  }
  
public:
bool sametypes(Base const &amp; rhs) const 
{
  return (typeid(*this) == typeid(rhs))
          ?true
          :false;
}

int compare(Base const &amp; rhs) const 
{
  return sametypes(rhs)
         ?compareInstances(rhs) 
         :2;
  }
  virtual ~Base(){};
};

class Derived: public Base 
{
int compareInstances
  (Base const &amp; rhs)const 
{
  if(typeid(Derived)!= typeid(*this))
   return 99;
  return (&amp;rhs == this)? 0 : 4;
}
};
  
class MoreDerived : public Derived 
{
// class in which no compareInstances 
// has been provided
};

// wrap the compare member function to 
// create operator == 
bool operator == 
  (Base const &amp; lhs, Base const &amp; rhs) 
{
  int value = lhs.compare(rhs);
  if (value == 99) 
    throw &quot;Sliced comparison&quot;;
  return value ? false : true;
}

// small test harness
    
int main( void ) 
{
  try{
    Base b1, b2;
    Derived d1, d2;
    cout &lt;&lt; (b1==b1) &lt;&lt; endl;
    cout &lt;&lt; (d1==d1) &lt;&lt; endl;
    cout &lt;&lt; (b1==b2) &lt;&lt; endl;
    cout &lt;&lt; (d1==d2) &lt;&lt; endl;
    cout &lt;&lt; (b1==d2) &lt;&lt; endl;
    cout &lt;&lt; (d1==b2) &lt;&lt; endl; 
    MoreDerived md1, md2; 
    cout &lt;&lt; (md1==md2) &lt;&lt; endl;
  }
  catch ( char const * message)
 { cout &lt;&lt; message &lt;&lt; endl; }
  return 0;
}
</pre>
<p>And a final thought, I wonder if a protected template member
function in the base class might work. No because it falls foul of
the same problem, how can we force its call in the most derived
class?</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
