Correct C++ tutorial chapter 2.1 "Classes" available (Windows, mingw/msvc/std)

A

Alf P. Steinbach

The eighth chapter (chapter 2.1) of my attempted Correct C++ tutorial is now
available, although for now only in Word format -- comments welcome!

Use the free & system-independent Open Office if you don't have Word.

Classes
<url: http://home.no.net/dubjai/win32cpptut/w32cpptut_02_01.zip>

Introduces the C++ language feature used to define new types, namely
classes. The focus in on creating safe and reusable classes. As a main
theme the jugs-puzzle program from chapter 1.4 is revisited, and the
chapter ends with an example program that solves the puzzle.

General URL:

<url: http://home.no.net/dubjai/win32cpptut/html/>

which provides chapters 1.1 and 1.2 as web-pages (HTML) in addition to the
original Word documents of all chapters in zipped format.

Contents, chapter 2.1:

1 [Background:] PODs, aggregates and pure C++ classes.
2 Classify and define general object member routines.
3 Place inline routine definitions in header files.
4 Design i/o-free classes.
5 Adjust a class to support ease of use, I.
6 Refactor user interface code as a class (class as module).
7 Make a class almost foolproof wrt. access to members.
8 Take charge of per-instance initialization with constructors.
9 Prevent implicit conversions by using explicit constructors.
10 Adjust a class to support ease of use, II.
11 Default constructors & the constructor call guarantee.
12 Use constructor initializer lists to initialize members.
13 A complete example of using classes in a program.

As before, the point of inviting comments is to _fix_ anything incorrect, or
the presentation, or whatever; your input is valuable, and you can thereby
help those who stumble across this tutorial and use it to learn C++.

Thanks in advance,

- Alf
 
T

Thomas Hansen

Alf P. Steinbach wrote:
[snip]
Contents, chapter 2.1:

I think a general "motivation" behind the REASONS to WHY the world
evolved into OOP instead of functional programming is lacking.
A big point in the whole OO motivation the way I see it (some people
will say it's a motivation behind only C++, I'd say OO) is typesafety!
(That's why C++ is THE best OO language even though lacking several big
OO features...)

If you encapsulate the function "wag()" in the class "DogTail" you
don't run the risc of of wagging() the Dog!
Or said in plain English, if you don't have typesafety you can run the
risc of trying to fly() a Submarine...

Another objective behind classes the way I see it is encapsulation and
datahiding.

Might be I've missed out several good points here, but my point is that
you should first MOTIVATE your readers before trying to teach them
something new which will seem unnessecary for them to spend time on at
first...

Also I'd stress the private keyword to a much bigger extend, after all
if the private data wasn't around in classes there would be no point in
having classes since the whole idea is encapsulating the functions
together with the data meaning that every operation possible for X
resides inside X which means you can easily see the X's interface and
easily spot all potential problem areas of X (X's public data and
functions)

I'd like to have a header called "The problem" and another called
"Encapsulation and private as your biggest friend" or something...

After all, classes are not about what you CAN do, they're about what
you CAN NOT do!!

Apart from that as usual off course excellent work Alf!

Btw, I'm still waiting for an answer regarding if I can mirror your
tutorials on the SmartWin website...

Thomas Hansen
 
A

Alf P. Steinbach

* Thomas Hansen:
Alf P. Steinbach wrote:
[snip]
Contents, chapter 2.1:

I think a general "motivation" behind the REASONS to WHY the world
evolved into OOP instead of functional programming is lacking.

All in good time... ;-)

For this chapter I just stressed how C++ has language features that
directly solve the problems encountered and solved less elegantly and less
safely in earlier chapters.

That's sort of personal motivation to start using classes; why the
world at large did so is, summary, (0) Vannevar Bush, I hope he's not
a relation to GW, and his technological insights, (1) simulations, Simula,
Norsk Regnesentral / Oslo University late 1960's, -> (2) Alan Kay, trying
to make sense of an Algol compiler that was actually Simula, and also
having picked up the ideas of Bush, -> (3) the Smalltalk GUI + language + OS +
computer + network + usability + pedagogical ideas project at Xerox Palo Alto
Research Center (Xerox PARC) in the middle 1970's to early 1980's, -> (4)
Bjarne Stroustrup doing simulations and as just about everyone else extending
C with OO ideas, cirka 1980, (5) the Apple Lisa, the fruits of Apple being
invited to evaluate Smalltalk, and not being as silly as HP or was it
Tektronix (who tried to make a GUI based on a vector graphics terminal), (6)
the Apple Macintosh, a kind of Lisa Light, (7) X11 and MS Windows, middle to
late 1980's, and I have to ask, whatever became of Taxi and all the other GUIs
for PC's, and not to forget, Niklaus Wirth's Oberon machine Lilith?


[snip]
Btw, I'm still waiting for an answer regarding if I can mirror your
tutorials on the SmartWin website...

I wasn't aware you'd asked. But by all means. _If_ you put a date on it
(when copied), a reference to the original, and wording to the effect that
the copy may not be the latest update. It is of course simpler to just
provide links. That way the site may even be listed in Google! :)
 
A

Andrew McDonagh

Thomas said:
Alf P. Steinbach wrote:
[snip]
Contents, chapter 2.1:


I think a general "motivation" behind the REASONS to WHY the world
evolved into OOP instead of functional programming is lacking.
A big point in the whole OO motivation the way I see it (some people
will say it's a motivation behind only C++, I'd say OO) is typesafety!
(That's why C++ is THE best OO language even though lacking several big
OO features...)

I might be mis-interpreting your comments here, but type safety little
to do with OO - its only relevant in UP Languages that are static typed.
Dynamic typed languages exist and are also OOPLs.

snipped remaining...


Andrew
 
C

Chris Riesbeck

Andrew McDonagh said:
Thomas said:
Alf P. Steinbach wrote:
[snip]
Contents, chapter 2.1:


I think a general "motivation" behind the REASONS to WHY the world
evolved into OOP instead of functional programming is lacking.
A big point in the whole OO motivation the way I see it (some people
will say it's a motivation behind only C++, I'd say OO) is typesafety!
(That's why C++ is THE best OO language even though lacking several big
OO features...)

I might be mis-interpreting your comments here, but type safety little
to do with OO - its only relevant in UP Languages that are static typed.
Dynamic typed languages exist and are also OOPLs.

And there are many strongly-typed functional programming languages.
 
T

Thomas Hansen

Chris said:
Andrew McDonagh said:
Thomas said:
Alf P. Steinbach wrote:
[snip]

Contents, chapter 2.1:


I think a general "motivation" behind the REASONS to WHY the world
evolved into OOP instead of functional programming is lacking.
A big point in the whole OO motivation the way I see it (some people
will say it's a motivation behind only C++, I'd say OO) is typesafety!
(That's why C++ is THE best OO language even though lacking several big
OO features...)

I might be mis-interpreting your comments here, but type safety little
to do with OO - its only relevant in UP Languages that are static typed.
Dynamic typed languages exist and are also OOPLs.

You're right off course, but both OO and strongly typing both try to
achieve the same goal.
They both want to make sure you don't try to fly with your submarine
and go under water with your plain...
OO by coupling the functions with the type and typesafety by making
sure you have the right type for the right task.
So to differentiate them in the conceptual idea is for most languages
wrong.
Most (good) languages that supports one also supports the other as long
as it can.
Off course after OO and typesafety came around in practical use lots of
other "features" where added (discovered) like reuse, data hiding,
encapsulation, cohesion and so on.
But in the beginning it was all about denying a submarine to fly!
And there are many strongly-typed functional programming languages.

But their motivation is still the same, OO is just after all an
extremity of typesafety.
Instead of having a method signature with a given type and issuing a
compiler warning/error when trying to call the method with the wrong
type you couple the method within the type making it impossible to make
your sub fly...
In practise you're right, in theory I must declare that I dissagree.

But I guess this is one of those subjects where we all do alot of
armwaving and "you know what I mean" stuff...
At least in the theoretical perspective.
Let the chicken and egg problem pass us unnoticed!
;)


Thomas Hansen
 
M

M Jared Finder

Most (all?) useful high level languages are strongly typed. The last
time I used a weakly typed high level language was programming in TCL,
which was difficult due to its weak typing. The languages I use now (C,
Python, Lisp) are all strongly typed.
But their motivation is still the same, OO is just after all an
extremity of typesafety.
Instead of having a method signature with a given type and issuing a
compiler warning/error when trying to call the method with the wrong
type you couple the method within the type making it impossible to make
your sub fly...
In practise you're right, in theory I must declare that I dissagree.

But I guess this is one of those subjects where we all do alot of
armwaving and "you know what I mean" stuff...
At least in the theoretical perspective.
Let the chicken and egg problem pass us unnoticed!
;)

It seems to me like you're looking at OO backwards. OO to me is about
polymorphism, where you think of things in terms of shared interfaces
and per-call implementations. What is dispatched on doesn't matter as
much to me as that the dispatch exists. The dispatch has the side
effect of type-safety, but that has never seemed to me to be the prime
motivation.

-- MJF
 
B

Ben Measures

Thomas said:
You're right off course, but both OO and strongly typing both try to
achieve the same goal.
They both want to make sure you don't try to fly with your submarine
and go under water with your plain...
OO by coupling the functions with the type and typesafety by making
sure you have the right type for the right task.
So to differentiate them in the conceptual idea is for most languages
wrong.

OOP emphasizes the following concepts:
Objects;
Abstraction;
Encapsulation;
Polymorphism; and
Inheritance.

Whether or not datatyping is done at compilation or runtime is
orthogonal to the above concepts [1].
But their motivation is still the same, OO is just after all an
extremity of typesafety.

Type safety merely mandates that the type of data objects is fixed and
does not vary over the lifetime of the object. This has nothing to do
with the concepts emphasized by OOP.
Instead of having a method signature with a given type and issuing a
compiler warning/error when trying to call the method with the wrong
type you couple the method within the type making it impossible to make
your sub fly...
In practise you're right, in theory I must declare that I dissagree.

Don't give your submarine a fly() method (unless you want it too, of
course) :p .

Or, if you mean a fly() method on a pilot, there are two equally valid
approaches:
1. Give it the ability to fly various classes: planes, blimps,
helicopters, dragons, etc.; or
2. Give it the ability to fly anything with yaw, pitch and roll controls.

Static typing is the first approach, dynamic typing is the second.


[1] With the exception of polymorphism. It can be argued that dynamic
typing automatically implies/enables (parametric) polymorphism without
needing any special language constructs.

TTFN,
 
A

Alf P. Steinbach

* Ben Measures:
Type safety merely mandates that the type of data objects is fixed and
does not vary over the lifetime of the object. This has nothing to do
with the concepts emphasized by OOP.

Type safety does not mandate that the type of data objects is fixed.

Smalltalk is a language that provides for type safety mainly via dynamic type
checking (I don't know whether there is static checking in modern Smalltalks).

C++ is a language that provides for type safety in some cases via dynamic type
checking.

I think it can be argued that Smalltalk is effectively more type safe than C++
(I also think the opposite can be argued, and then it boils down to what kinds
of type safety one cares about the most in any particular context).

However, I'm not sure that it's Good to single out type safety as what OO is
all about, and say that that is mainly what this tool is for. Rather, I think
a certain ease of providing type safety is a _requirement_ for any successful
OO mechanism, because it's difficult or meaningless to apply abstraction when
any object can be anything, or invalid wrt. the assumed type. C++ is
interesting in this respect because the C++ mechanisms for ensuring type
safety are very pragmatic ones where the difficulties mount exponentially the
stronger your goal of type safety is, and yet it has, in practice, been good
enough that C++ is a very successful language, used for very complex systems.
 
T

Thomas Hansen

M Jared Finder wrote:
[snip]
It seems to me like you're looking at OO backwards. OO to me is about
polymorphism, where you think of things in terms of shared interfaces
and per-call implementations. What is dispatched on doesn't matter as
much to me as that the dispatch exists. The dispatch has the side
effect of type-safety, but that has never seemed to me to be the prime
motivation.

Might be OO is polymorphism for you, but the single most importent
feature today with OO according to it's "creators" is Data Hiding also
known as Encapsulation!
You've got a "black box" you know if you feed it a direction it will
try to move in that direction, how this is being done is up to the
implementation to decide.
If this is a shared interface, a template policy, a concrete class is
less importent.
The point is that it may rely upon 500 non visible functions and 1000
private data-members which you don't even know exists!
Before OO we had stuff like (C) void * (typesafety), struct's where all
the data was "wide open" to manipulate for everyone (no encapsulation)
etc.
Basically if you had a bug somewhere you had a scope of "all the code".
After OO we could narrow that scope to only public functions and public
data in the class.
OO is about RESTRICTING developers from doing things (data hiding,
encapsulation, typesafety), not ENABLING them to do things
(polymorphism, inheritence etc.)

Ask your self how many times you've used virtual functions and how many
times you've used private data-members/function-members...
;)

[2_cents_of_zen_philosophy_in_the_morning]

The perfect class has no public members, no public data, can not be
copied, can not be assigned to, can not be instantiated and can not be
destroyed...
That's the perfect class!
(ref: If something is available it will cause trouble! )

[/2_cents_of_zen_philosophy_in_the_morning]



Thomas
 
T

Thomas Hansen

Ben Measures wrote:
[snip]
Type safety merely mandates that the type of data objects is fixed and
does not vary over the lifetime of the object. This has nothing to do
with the concepts emphasized by OOP.
dissagree.

Don't give your submarine a fly() method (unless you want it too, of
course) :p .

The difference between a typesafe language and a non typesafe language
is that a typesafe language has some kind of built in logic to
guarantee that you don't try to submit a "submarine" parameter to a
function which takes an "aeroplane" object...
Not totally unlike the princips of binding the "can do" (functions)
with the type (data) as in classes.
If this happens compile time you have a guarantee that it will NEVER
happen, if this happens runtime (dynamically typed languages) you'd
better hope your function is being called with the "wrong parameter" in
your Unit Tests!

Example:
var x = 5
var y = "5"
var z = x+y

What's the z variable containing here?
At least four possible candidates exists.
10, 55, "55" and "error"...

[snip]


Thomas
 
K

kanze

Thomas said:
Chris said:
Thomas Hansen wrote:
Alf P. Steinbach wrote:
[snip]
Contents, chapter 2.1:
I think a general "motivation" behind the REASONS to WHY
the world evolved into OOP instead of functional
programming is lacking. A big point in the whole OO
motivation the way I see it (some people will say it's a
motivation behind only C++, I'd say OO) is typesafety!
(That's why C++ is THE best OO language even though
lacking several big OO features...)
I might be mis-interpreting your comments here, but type
safety little to do with OO - its only relevant in UP
Languages that are static typed. Dynamic typed languages
exist and are also OOPLs.
You're right off course, but both OO and strongly typing both
try to achieve the same goal. They both want to make sure you
don't try to fly with your submarine and go under water with
your plain...

I'm not sure. In some ways, the goal of OO is to allow the
submarine to do whatever it has to to fly:). (Presumably, what
it has to do is different than what a plane has to do.)

The problem with the word OO is that it has become an in thing,
so people apply it to everything. I'm not sure what it really
means any more. And while I think that there is a sense in
which you are formally right concerning type safety, I suspect
that this isn't true for the most common uses of type safety and
OO.
OO by coupling the functions with the type and typesafety by
making sure you have the right type for the right task.

If I understood Booch correctly, OO implies dynamic
polymorphism. If you don't have virtual functions, it isn't
OO. The type safety aspect is secondary.
So to differentiate them in the conceptual idea is for most
languages wrong. Most (good) languages that supports one also
supports the other as long as it can. Off course after OO and
typesafety came around in practical use lots of other
"features" where added (discovered) like reuse, data hiding,
encapsulation, cohesion and so on. But in the beginning it
was all about denying a submarine to fly!
From what I understand about Smalltalk (the language for which
the word "object oriented" was invented), it was more a case of
empowering a submarine to fly, if it wanted to.
But their motivation is still the same, OO is just after all
an extremity of typesafety.
Instead of having a method signature with a given type and
issuing a compiler warning/error when trying to call the
method with the wrong type you couple the method within the
type making it impossible to make your sub fly...

That's a particularity of C++/Eiffel/Java/Ada95. It certainly
wasn't the case in Smalltalk.

When I think of strong static typing, or type safety, I think of
the Pascal family of languages. (Pascal arguably took strong
typing too far -- the length of an array was part of the type,
and you couldn't write a procedure which took an array of a
dynamically specified length.) I'd say that the OO part of C++
is involved in loosening the type system -- in a controlled
manner, because C++ remains statically typed. Never the less,
it allows me to pass objects of different types to the same
function, which is the opposite of strong static type safety.
 
T

Thomas Hansen

I'm not sure. In some ways, the goal of OO is to allow the
submarine to do whatever it has to to fly:). (Presumably, what
it has to do is different than what a plane has to do.)

;)
Well, I was trying to illustrate what could be a disastreous thing in a
weakly typed language lacking capabilities for coupling the type (data)
with the "can do" (functions)...
I assume you understand me, but for the clearity of other readers (this
post is going to several groups) I'll explain...

The above scenario of asubmarine trying to fly is a normal metaphor for
when things have gone REALLY bad!
These types of bugs where quite common to experience in earlier days
when you where sending void pointers around everywhere!
Also this is a problem many newbies experience even in more "secure"
languages like C++ etc, but they are more "difficult" to experience in
"better" languages...
You can imagine Churchill standing on Normandie in 1945 with something
he thought was supposed to be bombers but instead was submarines and
just when he tries to fly them he understands the mistake he has
done...
That's the type of problems you can drown in in a weakly typed language
lacking "OO" capabilities...

And that's where the "denial" comes into the picture, they both are
trying to "deny" you to fly a submarine...
Both OO and typesafety is all about denying!
Typesafety makes sure you don't supply a Submarine object to a fly
function and OO makes sure the Submarine class doesn't contain the fly
function.
The problem with the word OO is that it has become an in thing,
so people apply it to everything. I'm not sure what it really
means any more.

I can partially agree here, it's a "hyped" word...
In the late 90's they were almost selling fridges which was Object
Oriented!
(I wonder how you could inherit from the milk bottle and override the
Dispose function... ;)
And while I think that there is a sense in
which you are formally right concerning type safety, I suspect
that this isn't true for the most common uses of type safety and
OO.

No I am not formally right whatsoever!
You are!
But to separate two different mechanisms which occured around the same
time in evolution both trying to solve the same problems in the same
domain would be like separating brown eyes from blue!
Sure it can be done, but what's the point?
Those with brown eyes are neither dumber nor more intelligent then
those with blue eyes...
And they both percieve the world in roughly the same way.

(when that's said they off course have tons of qualities which the
other does not have but their one main biggest feature (denial) is
common for both)

If you see the evolution of C++ you will see that Bjarne implemented
features according to a priority list (at least he says so himself),
and the strongly typing system was one of the FIRST features he did,
long before e.g. exceptions and templates...
If I understood Booch correctly, OO implies dynamic
polymorphism. If you don't have virtual functions, it isn't
OO.
True!

The type safety aspect is secondary.

True!
I don't even think the typesafety is mentioned in the OO
"definition"...
the word "object oriented" was invented), it was more a case of
empowering a submarine to fly, if it wanted to.




That's a particularity of C++/Eiffel/Java/Ada95.
C#/Simula/Python/etc...

It certainly
wasn't the case in Smalltalk.

I know nothing about Smalltalk unfortunately...
But It sounds interesting if they managed to create something definable
as OO today without coupling functions within the types...
When I think of strong static typing, or type safety, I think of
the Pascal family of languages. (Pascal arguably took strong
typing too far -- the length of an array was part of the type,
and you couldn't write a procedure which took an array of a
dynamically specified length.) I'd say that the OO part of C++
is involved in loosening the type system

That might be true, but Bjarne had to take C compatibility into
account...
I think C++ wouldn't look like it did if it wasn't for C...
-- in a controlled
manner, because C++ remains statically typed. Never the less,
it allows me to pass objects of different types to the same
function, which is the opposite of strong static type safety.

( ...C compatibility yet again... )


Thomas Hansen
 
B

Ben Hutchings

Thomas said:
M Jared Finder wrote:

Might be OO is polymorphism for you, but the single most importent
feature today with OO according to it's "creators" is Data Hiding also
known as Encapsulation!
<snip>

Abstract data types (ADT) also provide encapsulation, whereas not
every version of OOP does. For example in Python privacy of object
attributes is merely a convention. Polymorphism is the really
essential feature of OOP.

Ben.
 
M

M Jared Finder

Thomas said:
M Jared Finder wrote:
[snip]
a

wrong

make

dissagree.


It seems to me like you're looking at OO backwards. OO to me is
about

polymorphism, where you think of things in terms of shared interfaces

and per-call implementations. What is dispatched on doesn't matter
as

much to me as that the dispatch exists. The dispatch has the side
effect of type-safety, but that has never seemed to me to be the
prime

motivation.


Might be OO is polymorphism for you, but the single most importent
feature today with OO according to it's "creators" is Data Hiding also
known as Encapsulation!
You've got a "black box" you know if you feed it a direction it will
try to move in that direction, how this is being done is up to the
implementation to decide.
If this is a shared interface, a template policy, a concrete class is
less importent.

I'm not sure how to say this, but what you are describing is
*abstraction*, and not object oriented design. Dictionary.com has the
following definition for abstraction: Ignoring or hiding details to
capture some kind of commonality between different instances.

Abstraction is a very good thing (and I'd say it is the fundamental
skill of thinking), but it is no more tied to OO than structured
programming or functional programming.

You deal with many non-OO abstractions every day -- function calls are
an abstraction of control flow, local variables are an abstraction of
memory allocation, assembly language is an abstraction of the
organization of a CPU's logic gates' interconnections. As you said, OO
is about abstraction in terms of shared interfaces, which requires
dynamic dispatch.
The point is that it may rely upon 500 non visible functions and 1000
private data-members which you don't even know exists!
Before OO we had stuff like (C) void * (typesafety), struct's where all
the data was "wide open" to manipulate for everyone (no encapsulation)
etc.
Basically if you had a bug somewhere you had a scope of "all the code".
After OO we could narrow that scope to only public functions and public
data in the class.

This is completely untrue. If there is a bug in your code, without
tests, you cannot know if the bug is on the client side or in the
implementation.

Again, abstraction helps here, not OO. (Remember, OO is just a type of
abstraction.) As long as your abstractions are kept clean, then you can
quickly isolate what causes a bug by looking at each abstraction
individually and seeing where the assumed behavior is different from the
actual behavior. See pre-conditions, post-conditions, and invariants,
another non-OO concept.
OO is about RESTRICTING developers from doing things (data hiding,
encapsulation, typesafety), not ENABLING them to do things
(polymorphism, inheritence etc.)

Ask your self how many times you've used virtual functions and how many
times you've used private data-members/function-members...
;)

I use abstractions much more than I use dynamic dispatch. But in
regards to your specific example, I rarely use C++-style private data
members and functions. The fact that I do most of my programming in C
and Lisp probably contributes to that. ;)
[2_cents_of_zen_philosophy_in_the_morning]

The perfect class has no public members, no public data, can not be
copied, can not be assigned to, can not be instantiated and can not be
destroyed...
That's the perfect class!
(ref: If something is available it will cause trouble! )

[/2_cents_of_zen_philosophy_in_the_morning]

Assuming the perfect computer would only run perfect programs, which can
only be written using perfect classes, we can deduce that the perfect
program can not do anything since the perfect classes can not do
anything, even exist. From this, it's simple enough to see that the
perfect computer is one that is off, because if it was on, the programs
it is running must be imperfect, since they are doing something.

I'll take my imperfect computer over your perfect computer every day of
the week. My computer is useful.

-- MJF
 
M

M Jared Finder

Thomas said:
I know nothing about Smalltalk unfortunately...
But It sounds interesting if they managed to create something definable
as OO today without coupling functions within the types...

I'd be interested in what you thought of the Common Lisp Object System.
I find its take on OO to be the most usable because it separates
dynamic dispatch and method combination from type definition. The cool
thing about this is that some OO design patterns are no longer needed.
The Visitor pattern is completely useless in CLOS specifically because
generic functions are separated from the tyranny of the classes.

-- MJF
 
K

kanze

Thomas said:
Well, I was trying to illustrate what could be a disastreous
thing in a weakly typed language lacking capabilities for
coupling the type (data) with the "can do" (functions)...
I assume you understand me, but for the clearity of other
readers (this post is going to several groups) I'll explain...
The above scenario of asubmarine trying to fly is a normal
metaphor for when things have gone REALLY bad!
These types of bugs where quite common to experience in
earlier days when you where sending void pointers around
everywhere!
Also this is a problem many newbies experience even in more
"secure" languages like C++ etc, but they are more "difficult"
to experience in "better" languages...

I certainly don't dispute that the lack of type safety can be a
problem. I'm all in favor of strong typing, preferably static.
But in some ways, typing and encapsulation are orthogonal. In
C, one classical way to encapsulate is to use a void* as a sort
of a universal handle. You have a function createXXX which
returns a void*, and an number of other functions
doSomethingWithXXX which take a void* as their first parameter.
This is highly encapsulated, and probably meets Alan Kay's
original definition of OO (although he might have also insisted
on polymorphism), but it is anything but typesafe.

[...]
I can partially agree here, it's a "hyped" word... In the
late 90's they were almost selling fridges which was Object
Oriented! (I wonder how you could inherit from the milk
bottle and override the Dispose function... ;)

There's an interesting annecdote at
http://c2.com/cgi/wiki?HeInventedTheTerm :).

Of course, exact meanings evolve -- Alan Kay has also been
quoted as saying "I made up the term 'object-oriented', and I
can tell you I didn't have C++ in mind" :). More to the point,
it seems clear from many things that Kay has said that he
considers full dynamic typing essential to OO; another OO guru,
Bernard Meyers, considers static typing essential to modern OO.
Alan Kay's earliest statements don't seem to consider
polymorphism essential, although most modern pundits (including
Kay, I think) do -- Booch distinguishes object oriented (with
dynamic polymorphism) from object based (all of the
encapsulation, but without polymorphism).
No I am not formally right whatsoever!
You are!
But to separate two different mechanisms which occured around
the same time in evolution both trying to solve the same
problems in the same domain would be like separating brown
eyes from blue! Sure it can be done, but what's the point?
Those with brown eyes are neither dumber nor more intelligent
then those with blue eyes... And they both percieve the world
in roughly the same way.

OK. By formally right, I meant simply that whatever concepts
you consider OO do interact in some way with a type system. The
type of an object is determined by the set of possible states
and the operations allowed on it. And OO is certainly concerned
with the set of possible states and operations.

What I see as a minimum in all definitions of OO (or even
Booch's object based) is encapsulation. Hiding the state, and
only exposing a subset (of state and operations -- typically
most of the operations, but little of the state). It's this
encapsulation which makes polymorphism possible. Rather than
requiring an exact type, it allows you to use any type which
supports the desired operations. In that sense, it goes in the
opposite direction of strong typing.

I would argue that strong (static) typing and OO are two
distinct developments, which occured at about the same time
(Pascal and Smalltalk), but which actually went in radically
different directions, at least at the start. Both brought
important advantages, and much of following the development
(including such languages as C++ and Eiffel) have been attempts
to merge these two developments.
(when that's said they of course have tons of qualities which
the other does not have but their one main biggest feature
(denial) is common for both)

Denial is NOT a characteristic of early OO. At least not of
Smalltalk. I would qualify early OO as more enablement. To get
back to your original example: I don't have to know what type an
object is to fly it. All I need is that it has a method "fly".
And that method can be added to any type I want.

Many (most) later "OO" languages take a more restrictive view;
that a class must explicitly declare that it supports a set of
operations, by deriving from a class which declares the
interface. Thus, for example, if the interface contains the
functions "fly", "land" and "takeoff", an object cannot support
flying without also supporting landing and taking off.
If you see the evolution of C++ you will see that Bjarne
implemented features according to a priority list (at least he
says so himself), and the strongly typing system was one of
the FIRST features he did, long before e.g. exceptions and
templates...

Yes, but as far as I can see, it was never a goal of C++ to be
"purely object oriented", or anything else but useful.
Encapsulation is a very useful feature. So is strong static
type checking.

Concerning the priorities of C++, it's also important to see
where it was coming from. C has fairly weak typing, and while
C++ has improved it greatly, there are still weak points, as
anyone who has done something like "aString += aDouble" can
attest to.

[...]
C#/Simula/Python/etc...

I'm not familiar with them, so I don't know:). On the other
hand, Smalltalk and CLOS definitly do not have static typing, at
all.

And of course, different communities use it in different ways.
There are a lot of interfaces in Java which simply deal with
Object, and leave you to guess the actual type, once you get it.
Which results in de facto dynamic type checking instead of
static. And numerous run-time errors instead of the compiler
complaining (but also certain freedoms which you don't have in
C++).
I know nothing about Smalltalk unfortunately...

I don't know it very well myself. But I know some of the
principles behind it.
But It sounds interesting if they managed to create something
definable as OO today without coupling functions within the
types...

It depends on what you mean by "definable". The basic principle
is simple: everything is an Object. Rather than "call
functions", you "send messages". The receiving object looks up
the message type in a table it contains, which maps message type
to method code, and either invokes the method code or
complains. I'm not too sure how it handles parameters, but if
it's anything like Lisp (on which it is based), the parameters
are just a list of Object, and it is up to the invoked method to
verify number and whether a given parameter supports the
needed operations.

I'd hate to try and develop robust software in such an
environment, but apparently, people do so, and do so well.
That might be true, but Bjarne had to take C compatibility
into account...
I think C++ wouldn't look like it did if it wasn't for C...

Certainly not. But I think that Bjarne rather favors (or at
least favored at one time) strong static type checking. At
least, one aspect of the evolution of C++ has been in this
direction.
( ...C compatibility yet again... )

Not at all. C compatibility certainly didn't require
inheritance and virtual functions. Which is what I was talking
about -- I declare my function to take a Base&, and you can pass
it a Derived1, or a Derived2, or any number of other types.

This is Smalltalk's enablement -- a possibility to take
liberties with the type system. In the case of C++, it's a
constrained enablement; you can't do just anything.

Of course, there is also a (static) polymorphism due to the fact
that a double implicitly converts to int (or even to char).
Which allows things like the "aString += aDouble" above. That
IS due to C compatibility:). (And I consider it more a bug
than a feature. Part of the price we had to pay for the
language to become widely used.)
 
T

Thomas Hansen

M Jared Finder wrote:
[snip]
I'm not sure how to say this, but what you are describing is
*abstraction*, and not object oriented design.

ehh...
And so?
I didn't state I was talking about OOD, I said (self quote) "the single
most importent feature of OO".
And all though abstraction is also possible to get in non-OO languages
it is far more difficult and doesn't come with the language "by
default" in the same extent as in OO languages.
Now if you bring in abstraction to the level where you can say that OP
code in binary form is an abstraction of electricity in a circuit and
thereby can declare that Assembler code have several abstraction layers
underneath it before hitting the iron I guess you can say all languages
have abstractions and be formally right...

Now relity check ( ;) ):
Where you can in C e.g. declare your "private" data directly in the
definition file you can declare them in your declaration file in C++
but still have them "hidden" from "outsiders".
And while you can in C choose not to declare your functions in any
declaration files and still use them as "private functions" you can in
C++ declare them in a declaration file and still be able to "hide"
them, you can even inherit from another class and only expose your
object as being of this other base type and thereby "hide" the fact
that this current object is not a "dog" but rather a "mammal" or
something.
To do the last in C requires bug prune code with lots of magic switches
and control flow statements...
(mark, the list of abstraction possibilities in C was not ment to be
exhaustive)

Those are FEATURES of C++. (and other OO languages)
But you are totally right it's called abstractions, that fact however
doesn't in any way contradict with the fact that they are still no
matter how you look at it the most importent features of OOP, OOD and
probably also OOX. (what ever that may be ;)

[snip]
Abstraction is a very good thing (and I'd say it is the fundamental
skill of thinking),

Depends on how many associations you can do before loosing control of
your mind...
;)
but it is no more tied to OO than structured
programming or functional programming.

Abstraction is in no way tied to OO, but OO is in all ways tied to
abstraction.
I guess you can say that the biggest generalized class OO inherits from
is abstraction, now that doesn't make abstraction a subclass of OO
though...
You deal with many non-OO abstractions every day -- function calls are
an abstraction of control flow, local variables are an abstraction of
memory allocation, assembly language is an abstraction of the
organization of a CPU's logic gates' interconnections. As you said, OO
is about abstraction in terms of shared interfaces, which requires
dynamic dispatch.

Yup, still OO's abstraction mechanisms are a 100 times better then NON
OO languages abstraction mechanisms... (at least the NON OO languages I
am familiar with)
This is completely untrue. If there is a bug in your code, without
tests, you cannot know if the bug is on the client side or in the
implementation.

If there is a bug in your code you can rest assured that it has at some
point emerged into your code through it's "abstraction parts" or it is
inside your code, meaning that no other code then the code having the
right to do so could possibly have changed the value of variable x, now
if variable x is a global variable "all the code" could have introduced
the value of variable x, if the variable x is a private data member of
a class only the class could itself have changed that value to the
garbage value!
(Suggested reading: Exceptional C++, especially the parts about
encapsulation)
Again, abstraction helps here, not OO.

Here you are right, OO languages have though still better abstraction
capabilities and mechanisms then NON OO languages... (yet again those I
have seen)
(Remember, OO is just a type of
abstraction.) As long as your abstractions are kept clean, then you can
quickly isolate what causes a bug by looking at each abstraction
individually and seeing where the assumed behavior is different from the
actual behavior. See pre-conditions, post-conditions, and invariants,
another non-OO concept.

Design by contract and asserts are powerful, and you can quickly
eliminate large portions of your code in debugging while looking for
bugs with them, however they don't help you in getting a clean
interface to your code or a good abstraction layer to client code
utilizing your code.
I use abstractions much more than I use dynamic dispatch. But in
regards to your specific example, I rarely use C++-style private data
members and functions. The fact that I do most of my programming in C
and Lisp probably contributes to that. ;)

Well OO languages has built in mechanisms to make it easy to make very
powerful and clean abstractions compared to other NON OO languages.
Does that make C++ better then C?
For most of my purposes the answer is YES!
But I realize other people have other needs and in other scenarios.
[2_cents_of_zen_philosophy_in_the_morning/]
Assuming the perfect computer would only run perfect programs, which can
only be written using perfect classes, we can deduce that the perfect
program can not do anything since the perfect classes can not do
anything, even exist. From this, it's simple enough to see that the
perfect computer is one that is off, because if it was on, the programs
it is running must be imperfect, since they are doing something.

I'll take my imperfect computer over your perfect computer every day of
the week. My computer is useful.

Well Zen philosophy often is like that, impossible to follow and of
more poetic value then concrete value...

Still the lessons learned are valuable, deny your code to do things by
default and open up on a demand basis.
Imagine how many bugs would have been gone if C++ didn't define default
CTOR's and CopyCTORs for classes...


Thomas Hansen
 
T

Thomas Hansen

Ben Hutchings wrote:
[snip]
<snip>

Abstract data types (ADT) also provide encapsulation, whereas not
every version of OOP does. For example in Python privacy of object
attributes is merely a convention. Polymorphism is the really
essential feature of OOP.

I guess you can argue for polymorphism being a part of encapsulation
since it hides away the details of the implementation.
At least that's the idea of polymorphism the way I see it.
You've got a mammal object with a public function "move" in the Bird
class which maps to "Fly" while in the Dog class this maps to "Walk".
So to state that polymorphism "hides" the internals of the function
wouldn't be directly wrong.
Probably a bad association by me to use the words Data Hiding!

Still I think that encpsulation (or "abstraction") is the single
largest and most importent feature of OO.
In just the same mattter that "type abstraction" is the single most
importent feature of generic classes. (templates)
Might be a definition of templates can't call itself confining unless
it's got this or that ( ref: export ;) still you wouldn't define the
biggest feature of templates to be it's ability to export
implementation into a definition file...?
In just the same manner I'd not define OO's best asset to be it's
ability to call overridden functions.
I'd like to define it as it's ability to abstract away the
implementation leaving only the "interface" (or public functions) left
for the client code to use...

Thomas Hansen
 
M

M Jared Finder

Thomas said:
M Jared Finder wrote:
[snip]
I'm not sure how to say this, but what you are describing is
*abstraction*, and not object oriented design.
ehh...
And so?
I didn't state I was talking about OOD, I said (self quote) "the single
most importent feature of OO".
And all though abstraction is also possible to get in non-OO languages
it is far more difficult and doesn't come with the language "by
default" in the same extent as in OO languages.
Now if you bring in abstraction to the level where you can say that OP
code in binary form is an abstraction of electricity in a circuit and
thereby can declare that Assembler code have several abstraction layers
underneath it before hitting the iron I guess you can say all languages
have abstractions and be formally right...
Now relity check ( ;) ):
Where you can in C e.g. declare your "private" data directly in the
definition file you can declare them in your declaration file in C++
but still have them "hidden" from "outsiders".

Many OO languages do not have the concept of private member
variables/functions. Every member is public, and it is only by
convention that certain members are off limits. Python, Smalltalk and
Lisp all come to mind as OO languages without the private qualifier.

Or do you consider Smalltalk, the language that made OO popular, not an
object oriented language precisely because it does not have the concept
of private members?

-- MJF
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top