Ryan's District Boards

Computer, programming, and webmaster help , support , tips and tricks => Tutorials Zone! => Internet webmaster computer programming technology tips and tricks => C++ / C / C# ....Tutorials => Topic started by: ben2ong2 on October 07, 2006, 04:00:01 AM

Title: C++ TIps-Square wars, or, just when you thought it was safe to use rectangles...
Post by: ben2ong2 on October 07, 2006, 04:00:01 AM
[see also <subtype>]


RESPONSE: pete@borland.com (Pete Becker), 23 Mar 93

   class Square
   {
   public:
       void SetHeight(int);
   };

   class Rectangle : public Square
   {
   public:
       void SetWidth(int);
   };

   Which doesn't make a lot of sense, either. Because I haven't told you
   what I want to do with these things.

   Here's a better example:

   class ScreenSquare
   {
   protected:
       int Height;
   public:
       void SetHeight(int);
       virtual void Draw();
   };

   class ScreenRectangle : public ScreenSquare
   {
   protected:
       int Width;
   public:
       void SetWidth(int);
       virtual void Draw();
   };

   While I like the abstract formulation in terms of invariants, it simply
   doesn't apply here.


   "Is-a" isn't a magic incantation. It's a guide to design,
   but you still have to know where you're going.


RESPONSE: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller), 23 Mar 93

   Yes. And not that in my terminology, the ScreenRectangle
given above, while a perfectly good class, is NOT a PURE subclass of
ScreenSquare because it adds extra state space in the form of
'Width'.

   Its easy to see this: just delete the Draw and Set functions,
and what you have left is just composition:

   struct S {
      int Height;
   };

   struct R : public S {
      int Height;
   };

which is semantically equivalent to

   struct R {
      S h;
      int Width;
   };
   
However, the following IS pure subclassing, provided appropriate
comments as to the semantics are added:

   class Sqr {
      int Height;
   public:
      virtual void SetHeight(int h) {Height=h;}
      virtual void SetWidth(int w) {Height = w;}
      virtual void Draw()const;
   };

   class Rct : public virtual Sqr {
      int Width;
   public:
      void SetWidth(int w) {Width=w;}
      void Draw()const;
   };

This allows independent control of the height and width of BOTH
a square and a rectangle. You need to add a comment perhaps
that says that you shouldnt assume that when you change the
height of a square the width remains unchanged.

In particular, although it is true that height == width for
a square, this MUST be just an implementation detail and MUST NOT
BE STATED AS A CONSTRAINT.

That is, there is a crucial difference between the properties
that Sqr happens to actually have, and those that it is
declared to have.


RESPONSE: krc@wam.umd.edu (Kevin R. Coombes), 23 Mar 93

...the last time this discussion went around, I argued the side that
insisted that a Square ISA Rectangle. Since that time, I've begun to
change my mind. It's true that a constant square ISA rectangle; the
problem arises when you're allowed to modify the objects...


RESPONSE: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller), 24 Mar 93

   Its absurd to argue whether a square is
a rectangle or not without saying what a square and a rectangle ARE.

   As far as I'm concerned, a square is a place where people
meet at fountains.

   You have not changed your argument so much as your definition
of what a square/rectangle is.

   If some transform exists:

   t (R) -> R

and S < R (subset), then there is a map

   t (S) -> R

that is, a member function 'Xscale' exists, but it cannot be
a mutator. A mutator must have the form:

   t(X) -> X

or, more generally,

   t(X, p1, p2, .... ) ->X

and the image t(S) of t|S (restriction) in R is not a subset of R.

The mathematics is elementary. What is hard to understand is that
whether something is a subclass of something else depends on
their respective definitions.

In particular, in C++, a rectangle with two equal sides IS NOT A SQUARE,
because in C++ two things have the same type if and only if they
are declared to have the same type.


RESPONSE: williamc@aifh.ed.ac.uk (William Chesters), 24 Mar 93

You're getting it the wrong way wround.  The essence, if you like, of
a rectangle is that it is a polygon all of whose internal angles are
right angles.  Certainly a square satisfies this defining property.
So a square isa rectangle.  So the fact that it can't change its
width in proportion to its height shows that not all rectangles can,
ie, in general, rectangles can't.


RESPONSE: pete@borland.com (Pete Becker), 24 Mar 93

   On the other hand, there's the old joke: how many legs does a dog have
if you call its tail a leg?  Answer: four. Calling the tail a leg doesn't make
it one.
   Similarly, asserting that there is only one true definition of a
rectangle, and that therefore a square must be a rectangle, doesn't make it
so. Especially if a consequence of applying that definition is that you have
to throw away useful properties of rectangles such as being able to change
their dimensions independently.
   I can't imagine writing a window manager without being able to
independently resize the two dimensions of each screen rectangle. And I refuse
to go through some circumlocution to avoid calling them rectangles. They
clearly are rectangles.