Re: A good Point/Size implementation? Re-using with different names
On 12/11/2014 1:21 PM, JiiPee wrote:
On 11/12/2014 17:16, Victor Bazarov wrote:
On 12/11/2014 11:33 AM, JiiPee wrote:
I am creating these Point (x, y) and Size (width, height) classes.
Because they are pretty much the same thing I would like to re-use the
Point class.
In what way would you "re-use" it?
So that Size would somehow use Point's code. So when I say:
Size s = Size(2,3);
all this code is from Point class. So Size is just another name for
Point kind of. The only difference being that I want Size to have width
instead of x member. [..]
My partially rhetorical question was in an attempt to draw your
attention that a Size *is not* a Point. You will probably see it later
when you add some functionality to Point, which you don't want to see in
Size, and vice versa.
What you need is the common base class for those. Find a copy of James
Coplien's "Advanced C++" (IIRC it was published in 1991) and read it
carefully. A quick hint: don't try to substitute one class for another
if there is no true substitution between them.
Here is one example of what some consider a fault in the design. As is
often suggested, a point in N-dimensional space *is a* vector in that
space. However, when some linear algebra interface is developed, we
need to remember that affine transformations when applied to a point
produce a different result than those applied to a vector (the
translation should be ignored for the latter transform). So, I have
seen more than once
typedef vectorNd pointNd;
and then somewhere
...
pointNd xformAsPoint(const pointNd &) const;
along with
vectorNd xformAsVector(const vectorNd &) const;
So, what's wrong, you might ask. Here is what's wrong. First off, I
want those two types to be distinct and have two *overloaded* functions
'xform' ("transform"), one for *a point* and one for *a vector*.
Second, I want to never be able to pass a point where a vector is
expected (and vice versa), so not to make a mistake. IOW, I want to be
able to require a cast made when one is converted into (treated as) the
other.
Such requirements prevent mistakes that the compiler cannot catch.
So, in your case, I strongly recommend figuring out what is common
between a Point and a Size, extracting that common portion into another
class and using that class as a base for both Point and Size.
Constructors are now (in C++11, and later) inherited, so you should be
able to do what you *already* want, i.e. to share the constructor
between those two types (three types, actually). But don't rush into
implementation. Design them first. Correctly.
V
--
I do not respond to top-posted replies, please don't ask