From: Francis Glassborow on
Pat wrote:

> Wow. I think I'm finally seeing the light. I just tested this and
> you're right. I can define these overaloaded operators just like
> "ordinary" functions, passing my Point structures (or any other type) as
> arguments. No need for all the formalism of a class. I think I've now
> come full circle, as this is the solution I was originally asking for.
> I'm surprised the three or so C++ books I've been referring to didn't
> mention this when introducing operator overloading, instead of making it
> seem like it was a class-only feature. At least I know how classes work
> now.
>
> Thanks for pointing the way! I appreciate it. :^) -Pat
>

I think you are completely missing the point. Unless there is a very
good reason to have public data you should avoid it. That means avoid
having structs as opposed to classes (though there is minuscule
difference between them in C++.

Or more to the point, keep your data private because it allows future
change.

For example, your point class uses Cartesian coordinates. Suppose you
later want to change to polar coordinates. If you have made your data
public it means a substantial rewrite but if your data is private it
will only involve rewriting the access functions. Even better is that
you could have two implementations of your point class with identical
public interfaces but optimised internally for different purposes
(rotations work better in polar and translations work better in
Cartesian) You can then benchmark your application to see which works
best with it.

So start with:

class Point {
public:
Point(double x = 0.0, double y = 0.0);
double x();
double y();
private:
double x_;
double y_;
};

Later you can add (or replace the x_ and y_ with ) argument and modulus
data members and change the implementation of the public access
functions. Yes it can get quite complicated but the point is that all
the complexity is confined to the implementation of Point and users of
Point have no need to concern themselves with exactly how a point is
represented.

And, yes, I know that there are some design issues particularly with the
constructors but the point I am trying to make is that public data locks
you into a particular representation of a point, but private data
maintains the abstraction (the concept of a point is independant of the
way we choose to identify it).

From: Francis Glassborow on
Pat wrote:

> Wow. I think I'm finally seeing the light. I just tested this and
> you're right. I can define these overloaded operators just like
> "ordinary" functions, passing my Point structure (or any other type) as
> arguments. No need for all the formalism of a class. I think I've now
> come full circle, as this is the solution I was originally seeking. I'm
> surprised the three or so C++ books I've been referring to didn't
> mention this when introducing operator overloading, instead of making it
> seem like it was a class-only feature. At least I know how classes work
> now.

NO they did not. Every reasonable book on C++ clearly states that in C++
the only difference between a class and a struct is its default access.
They then confine themselves to good practice by presenting classes
because every author of respectable C++ books understands that data
should be private unless there are exceptionally good reasons for making
it otherwise.

They expect their readers to use the class keyword and private data.
They also expect their readers to remember that what works for a class
works for a struct as long as default access is not an issue.

Curiously, these days experienced programmers write their class
interfaces in 'need to know' order which means that they start with the
public interface. This means that, in a sense, the default is irrelevant
because they override it. But they still use the 'class' keyword and
reserve 'struct' for the cases where they want to draw attention to the
fact that this time they are going to avoid using data abstraction.
From: Pat on
Francis Glassborow wrote:
> Pat wrote:
>
>> Wow. I think I'm finally seeing the light. I just tested this and
>> you're right. I can define these overloaded operators just like
>> "ordinary" functions, passing my Point structure (or any other type) as
>> arguments. No need for all the formalism of a class. I think I've
>> now come full circle, as this is the solution I was originally
>> seeking. I'm surprised the three or so C++ books I've been referring
>> to didn't mention this when introducing operator overloading, instead
>> of making it seem like it was a class-only feature. At least I know
>> how classes work now.
>
> NO they did not. Every reasonable book on C++ clearly states that in C++
> the only difference between a class and a struct is its default access.
> They then confine themselves to good practice by presenting classes
> because every author of respectable C++ books understands that data
> should be private unless there are exceptionally good reasons for making
> it otherwise.
>
> They expect their readers to use the class keyword and private data.
> They also expect their readers to remember that what works for a class
> works for a struct as long as default access is not an issue.
>

Ok. I remember reading something about the similarity between structures
and classes, but that was in the section on classes. What I was mainly
trying to get at is that the topic of operator overloading could have
been introduced earlier (prior to classes). I can understand the
reluctance in doing so, if it would promote bad programming. But at
least for myself, I would like to have know about it sooner, even if
classes are generally the better vehicle for it.
From: Francis Glassborow on
Pat wrote:
> Ok. I remember reading something about the similarity between structures
> and classes, but that was in the section on classes.

Exactly, because that is all that a struct is in C++, it is a class with
public default access.

What I was mainly
> trying to get at is that the topic of operator overloading could have
> been introduced earlier (prior to classes).

No it cannot. In order to overload an operator you need a user defined
type. In C++ there are fundamentally two user defined types; classes
(that can be introduced by the keywords class or struct, and in a very
limited form by the keyword union) and enums.

You are confusing keywords with concepts. C++ has the concept of a class
as a user defined type in which the user specifies both the data
structure and the behaviour. Many years of experience has shown that in
the overwhelming majority of cases there is a great deal of benefit
gained from retaining control over the choice of data structure and that
the user is almost invariably only concerned with behaviour and
sometimes performance.

I can understand the
> reluctance in doing so, if it would promote bad programming.
No, it isn't that but simply that the writer has to choose when to
introduce the idea of an abstract type. struct is a hangover from C, and
without the C ancestry there would not be a struct keyword in C++.

But at
> least for myself, I would like to have know about it sooner, even if
> classes are generally the better vehicle for it.

You are still clinging to the idea that in some way a struct is
significantly different to a class. It isn't in C++. They are the same
thing. Yes, if you need to write code that is valid C as well as being
C++ you may need to use a minimalist struct, but in that case you will
not have any user provided operator overloading. The minute you want
operator overloading you want C++ and C++ uses classes even if they are
sometimes introduced with the struct keyword.
From: Pat on
Francis Glassborow wrote:
> Pat wrote:
>
>> Wow. I think I'm finally seeing the light. I just tested this and
>> you're right. I can define these overaloaded operators just like
>> "ordinary" functions, passing my Point structures (or any other type) as
>> arguments. No need for all the formalism of a class. I think I've
>> now come full circle, as this is the solution I was originally asking
>> for. I'm surprised the three or so C++ books I've been referring to
>> didn't mention this when introducing operator overloading, instead of
>> making it seem like it was a class-only feature. At least I know how
>> classes work now.
>>
>> Thanks for pointing the way! I appreciate it. :^) -Pat
>>
>
> I think you are completely missing the point. Unless there is a very
> good reason to have public data you should avoid it. That means avoid
> having structs as opposed to classes (though there is minuscule
> difference between them in C++.
>
> Or more to the point, keep your data private because it allows future
> change.
>
> For example, your point class uses Cartesian coordinates. Suppose you
> later want to change to polar coordinates. If you have made your data
> public it means a substantial rewrite but if your data is private it
> will only involve rewriting the access functions. Even better is that
> you could have two implementations of your point class with identical
> public interfaces but optimised internally for different purposes
> (rotations work better in polar and translations work better in
> Cartesian) You can then benchmark your application to see which works
> best with it.
>
> So start with:
>
> class Point {
> public:
> Point(double x = 0.0, double y = 0.0);
> double x();
> double y();
> private:
> double x_;
> double y_;
> };
>
> Later you can add (or replace the x_ and y_ with ) argument and modulus
> data members and change the implementation of the public access
> functions. Yes it can get quite complicated but the point is that all
> the complexity is confined to the implementation of Point and users of
> Point have no need to concern themselves with exactly how a point is
> represented.
>
> And, yes, I know that there are some design issues particularly with the
> constructors but the point I am trying to make is that public data locks
> you into a particular representation of a point, but private data
> maintains the abstraction (the concept of a point is independant of the
> way we choose to identify it).
>

Thanks for the example. I probably will end up using a class because of
the flexibility it allows with the public interface. I would like to be
able to define point objects based on either cartesian or polar
coordinates, and I think that would be easier to set up with a class. I
do have one question though. Doesn't a structure also provide
abstraction? For example, with overloaded operators I can write
relations like,

Point p3 = p1 + p2;
Point p4 = 5*p1;
....

which are independent of how the data is stored internally. So just like
with a class, wouldn't this just require rewriting the function
definitions to change the internal structure?