Sunday, August 11, 2013

FeedaMail: Comments for Sutter̢۪s Mill

feedamail.com Comments for Sutter's Mill

Comment on GotW #6b Solution: Const-Correctness, Part 2 by Felipe

I guess I’m going into a very different subject here, but the original version of this item got me thinking about the difference between the state of an object and equivalence between objects. I’ve been looking for a good forum to put this out for discussion. What follows more or less reflects my train of thought.

Consider the following client code, assuming Polygon provides {operator==} and {operator<<}:

      Polygon p1, p2;        p1.AddPoint( Point(0.0,0.0) );      p1.AddPoint( Point(1.0,0.0) );      p1.AddPoint( Point(1.0,1.0) );      p1.AddPoint( Point(0.0,1.0) );        p2.AddPoint( Point(0.0,0.0) );      p2.AddPoint( Point(1.0,0.0) );      p2.AddPoint( Point(1.0,1.0) );      p2.AddPoint( Point(0.0,1.0) );        std::cout << "The area of p1 is = " << p1.GetArea() << std::endl;      std::cout << "Are they equal? " << ( (p1==p2)?"Yes!":"No :(" ) << std::endl;      std::cout << "What do they look like?\n";      std::cout << "p1: " << p1 << std::endl;      std::cout << "p2: " << p2 << std::endl;  

The objects p1 and p2 are certainly equivalent, i.e. they represent two identical polygons, but after the call to {p1.GetArea()} (which happens to be a const member function that alters a mutable private member variable) their state is different. My questions are:

1. What should {operator==} test for?
2. What should {operator<<} print?

My own answers:

1. {operator==} should test for equivalence, and thus never compare a mutable member variable (is that a good guideline?). However, should one call {GetArea()} in the body of {operator==} and thus possibly change the object's state?
2. {operator<<} should print all the observable attributes of the object, not its state (i.e. printing the value of {GetArea()}, not the current value of the mutable variable that represents the area). One could, in fact, provide a separate method (perhaps called {serialize()}) that would print the state in case that's meaningful.

So seems that my approach distinguishes between 'observable state' and 'implementation state', and the two operators should reflect the former. I then wonder, why not make them always non-member (free), non-friend functions?

A few other questions come up as a consequence of my own answers, but I'll leave it at that and hope for some comments from more illuminated folks.

Disclaimer: The actual mechanics of comparing 2 polygons can get as complicated as one wishes, I'm just taking a naive, intuitive approach and don't really care about the innards, mostly the interface. Also, apologies in advance if this rant is way off topic.

Read More »
 
Delievered to you by Feedamail.
Unsubscribe