On Wed, 2015-03-04, Geoff wrote:
> On Wed, 04 Mar 2015 13:46:38 +0000, JiiPee <
n...@notvalid.com> wrote:
>
> [snip]
>>
>>Peter: But what fundamental difference is there with age and coordinate
>>variables? Why the other one should be hidden
>>as a private and the other one not?? Tell me....
>
> The question you seem to be asking, in a long and tortuous way, is:
> At what point does an object become complex enough to deserve being a
> class?
What is a class, then? They are all types: structs/classes, various
built-in types, enums (old and new) ...
I think you really mean "At what point should I create a new, distinct
type for this thing I'm modelling, rather than let it join and mingle
with the other happy integers?"
> Answer: it depends on the abstraction of the object and the design
> goals for that object.
You mean, I think, "object" in the sense "some concept I have to
manage in my code", like age or coordinate.
Then I agree.
> In the case of an integer or any of the intrinsic types, they are
> probably not complex enough to deserve a class or the usage of the
> object would be more cumbersome as a class that it is as a naked
> object.
I find that untrue. One of the eye-openers for me over the years has
been how useful it is to make up distinct types for things which could
have been represented as an int. And how few the drawbacks are.
- You can document the type.
- You can restrict operations to things which make sense.
- You can avoid accidentally mixing it with other integers.
- You can overload on the type.
- You can select how it's formatted on a std::ostream.
- etc
In general, if you think of something as a distinct thing, it probably
deserves its own type. That's what they're there for, and that's what
C++ is really good at.
For example, I once maintained a code base with something like
struct Statistics {
unsigned long rx;
unsigned long tx;
unsigned rx_err;
// a dozen more
};
We constantly forgot to initialize them all to zero in the constructor,
until I realized that the right thing to do was to create an
Accumulator<T> which initialized itself to 0, and only supported
operator++() and printing itself.
Then there was the incident with the sequence numbers (my side, the
remote side's, the data plane's) which were mixed up in one odd code
path, and almost sent me to India to troubleshoot. Next time, I
created types LocalSeqno, RemoteSeqno, ... and that bug became
impossible.
> One wouldn't write a class for unsigned int age but one would
> write a class for object Student, possessing attributes, age, grade,
> sex, GPA, ID_Number, etc.
>
> It's a design choice that is dictated by the scope of the program and
> it's goals.
That contradicts your "one wouldn't write a class for unsigned int
age". If ages are important to the problem you're solving, make Age a
type. If it's just an unimportant property of a Student and not
really used elsewhere, keep it as an int.
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/
snipabacken.se> O o .