471,092 Members | 1,859 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,092 software developers and data experts.

getters and setters

I'm familiar with get and set function paradigms from Java, but what's
the recommended design for such in C++? Should it be like so:

foo& getFoo();
void setFoo(foo& f);

or like so:

foo& foo();
const foo& foo() const;

or some combination of the above?

--
I am only a mirage.
Jul 23 '05 #1
32 20919
kelvSYC wrote:
I'm familiar with get and set function paradigms from Java, but what's
the recommended design for such in C++? Should it be like so:

foo& getFoo();
void setFoo(foo& f);

or like so:

foo& foo();
const foo& foo() const;

or some combination of the above?


My preference is:

class C{
int x() { return _x; }
void x(int x_) { _x = x_; }
private:
int _x;
};

But I believe I am not in the majority on this.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #2
kelvSYC wrote:
I'm familiar with get and set function paradigms from Java, but what's
the recommended design for such in C++? Should it be like so:

foo& getFoo();
Add

foo getFoo() const;

or change to

foo const& getFoo() const;

there is no need to get 'foo' as a ref to non-const unless you want to
change it, and for that there is 'setFoo()'.
void setFoo(foo& f);

or like so:

foo& foo();
const foo& foo() const;

or some combination of the above?


I prefer the former (with my corrections). I even _recommend_ the former.
The latter is rather confusing. Unless, of course, you consider
conversion operators:

operator foo&();
operator foo() const;

So to answer your question, I don't know what "the recommended design" is
since everybody has their preferences.

V
Jul 23 '05 #3
Steven T. Hatton wrote:
kelvSYC wrote:

I'm familiar with get and set function paradigms from Java, but what's
the recommended design for such in C++? Should it be like so:

foo& getFoo();
void setFoo(foo& f);

or like so:

foo& foo();
const foo& foo() const;

or some combination of the above?
My preference is:

class C{
int x() { return _x; }


int x() const { return _x; }
void x(int x_) { _x = x_; }
private:
int _x;
};

But I believe I am not in the majority on this.


I can see why. If the function takes an argument, then the name of the
function should be a verb.
C c;
c.x(5);

what does that do? Now, if it were

c.x() = 5;

or

c.set_x(5);

I'd not argue.

V
Jul 23 '05 #4
* kelvSYC:

I'm familiar with get and set function paradigms from Java, but what's
the recommended design for such in C++?
That's platform-specific, and so it's really off-topic, but probably
you couldn't know that.

Why it's platform-specific:

In Java getters and setters are accessible for outside software, e.g.
the development environment, because Java supports introspection and
has a de facto standard for naming those beasts. C++, in contrast,
does not (yet) support introspection, and has no standard (de facto or
otherwise) for naming the beasts. Thus, in C++, they are only useful
if you program against some standard such as Ole Automation, that
supports "properties". Otherwise, it's wise to generally _not have_
getters and setters, except for classes like e.g. Point and Rectangle
that at least conceptually are just collections of named values.

Should it be like so:

foo& getFoo();
void setFoo(foo& f);
Except if some standard requires it, IMO you should avoid names like
'getcos', 'getsin', 'getmax', 'getabs', 'getlength', 'getsize', and
especially 'getFoo'.

or like so:

foo& foo();
That's so bad it reminds me of Microsoft (they actually do that): don't
use the type name as the function name, please.

const foo& foo() const;


How about

class Point
{
private:
long myX;
long myY;
public:
Point(): myX( 0 ), myY( 0 ) {}
Point( long x, long y ): myY( y ), myX( x ) {}

long x() const { return myX; }
long y() const { return myY; }

void setX( long x ){ myX = x; }
void setY( long y ){ myY = y; }
// ...
};

where simultanous setting of x and y is provided by the Point constructor.

General advice: forget Java when you use C++.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #5
Victor Bazarov wrote:
Steven T. Hatton wrote:
kelvSYC wrote:

I'm familiar with get and set function paradigms from Java, but what's
the recommended design for such in C++? Should it be like so:

foo& getFoo();
void setFoo(foo& f);

or like so:

foo& foo();
const foo& foo() const;

or some combination of the above?

Basically, you are talking about what some people call the JavaBeans naming
conventions.
JavaBeans Spec is a worthwhile read for any programmer, Java or better.

http://java.sun.com/products/javabea...api/index.html

My preference is:

class C{
int x() { return _x; }
int x() const { return _x; }


Agreed.
void x(int x_) { _x = x_; }
private:
int _x;
};

But I believe I am not in the majority on this.


I can see why. If the function takes an argument, then the name of the
function should be a verb.


Bah! If it were more complex, I would agree that an English (or other
natural language) verb would be advisable, but in C++, if I follow my
convention, "void x(int x_) const;" is a verb, "set" is /implied/.

http://www.ambysoft.com/javaCodingStandards.html
See page 54 javaCodingStandards.pdf

Also here:

http://doc.trolltech.com/qq/qq13-apis.html

I hold Matthias Ettrich in the highest regard. He is one of the most
successful programmers in the world. To some extent, I believe his advice
applies better to the kinds of APIs he works with, than to the kind of
stuff I'm doing. Nonetheless, I am not fully sold on the setMember and
maybe getMember, naming convention. There is merit in the suggestion to
use whole words rather than abbreviations. That way, you don't have to try
and remember both the concept and the shortcut. OTOH, Stroustrup makes a
good point about the expressive power of consice symbols such as operators.
Sometimes x, y, z, are more expressive than widthComponent,
heightComponent, depthComponent.
C c;
c.x(5);

what does that do?
If you see a variable-looking function name, and no verbage tacked onto it,
It's a "set" function. I will agree that bool isSomeState(); and
setSomeState(bool s); can be marginally more expressive than bool
someState(); someState(bool s);
Now, if it were

c.x() = 5;

or

c.set_x(5);

I'd not argue.

V


Germanic languages do not have genuine preposition.

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #6
On 2005-06-20 23:17:46 +0100, al***@start.no (Alf P. Steinbach) said:
How about

class Point
{
private:
long myX;
long myY;
public:
Point(): myX( 0 ), myY( 0 ) {}
Point( long x, long y ): myY( y ), myX( x ) {}

long x() const { return myX; }
long y() const { return myY; }

void setX( long x ){ myX = x; }
void setY( long y ){ myY = y; }
// ...
};


struct Point {
long x ;
long y ;
} ;

....
Point mouse = ::getMouse() ;
if (mouse.x > 0) {
...
}

You don't need getters/setters. Accept the bare truth!
Don't write
class XXX {
private:
That's redundant
Don't write
class XXX {
public:
That's stupid
write
struct XXX {
and you're done.

this private/protected/public business is one of the most
baffling, useless, ill thought of, over abused contribution
of C++

"I invented the term Object-Oriented, and I can tell you I did not have
C++ in mind."
- Alan Kay
--
JFB

Jul 23 '05 #7
"Steven T. Hatton" <ch********@germania.sup> wrote in
news:0J********************@speakeasy.net:
Bah! If it were more complex, I would agree that an English (or other
natural language) verb would be advisable, but in C++, if I follow my
convention, "void x(int x_) const;" is a verb, "set" is /implied/.


'Implication' is often not totally clear. What the writer thinks he's
implying may not be the same as what the reader thinks he is. This is
especially true if the two dont read things the same way, or there is some
language barrier.
Jul 23 '05 #8
kelvSYC wrote:
I'm familiar with get and set function paradigms from Java
but what's the recommended design for such in C++?
Should it be like so:

foo& getFoo(void);
It isn't usually a good idea
to return a [non-const] reference to an object
which is part of another object
unless that other object is a *container*
for objects of type Foo.

const
Foo& getFoo(void) const;

would be better and it can be applied to const objects.
void setFoo(Foo& f);
Try to avoid void functions.
Return a reference to the modified object
so that this function can be used in an expression.
or like so:

Foo& foo(void);
const
Foo& foo(void) const;

or some combination of the above?


Yes. The get and set prefixes are superfluous.

class Bar {
public:
class Foo {
private:
// representation
int I;
public:
Foo(int i = 0): I(i) { }
};
private:
// representation
Foo F;
public:
const
Foo& foo(void) const { return F; }
Foo& foo(void) { return F; }
};

If you are going to return a non-const reference
to an object which is *not* an element of a container,
you should retain control over the definition
of that object so that you can change it later
without breaking any code that uses it.
In the above example, nesting the definition of Foo
inside the definition of Bar guarantees that
the Bar library developer retains control
over the definition of Foo.
Jul 23 '05 #9
verec wrote:
You don't need getters/setters.
Accept the bare truth!

Don't write
class XXX {
private:
That's redundant.
So what?
Don't write
class XXX {
public:
That's stupid
write
struct XXX {
and you're done.

This private/protected/public business
is one of the most baffling, useless,
ill thought of, over abused contribution of C++.
Does that mean that you are prepared
to propose an alternative contribution?
"I invented the term Object-Oriented,
and I can tell you I did not have C++ in mind."
- Alan Kay


But Alan Kay says nearly the same thing about Java.
So what *did* Alan Kay have in mind
when he coined the term "object oriented"?
Smalltalk.
Alan Kay coined the term "object oriented"
to help describe his new computer programming language
and *not* to classify computer programming languages.
Other people used the term to classify programming languages
including the inventors of Simula
which, according to Alan Kay, "inspired" Smalltalk.
Jul 23 '05 #10
E. Robert Tisdale wrote:
kelvSYC wrote:
.... Try to avoid void functions.
Return a reference to the modified object
so that this function can be used in an expression.


That seems like reasonable advice. There's also another option in some
cases.

ParentWidget* pw(new ParentWidget);
ChildWidget* cw(pw->addChildWidget(new ChildWidget));

Or a real world example:
http://xml.apache.org/xerces-c/Apach...BindingL3.html
virtual DOMNode* insertBefore(DOMNode* newChild, DOMNode* refChild) = 0;
virtual DOMNode* replaceChild(DOMNode* newChild, DOMNode* oldChild) = 0;
virtual DOMNode* removeChild(DOMNode* oldChild) = 0;
virtual DOMNode* appendChild(DOMNode* newChild) = 0;
or like so:

Foo& foo(void);
const
Foo& foo(void) const;

or some combination of the above?


Yes. The get and set prefixes are superfluous.


So I'm the only one, eh?

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #11
Steven T. Hatton wrote:
E. Robert Tisdale wrote:
[...]
Yes. The get and set prefixes are superfluous.


So I'm the only one, eh?

No, of course not. You're in good company.
Jul 23 '05 #12
"kelvSYC" <ke*****@no.email.shaw.ca> schrieb im Newsbeitrag
news:200620051552452355%ke*****@no.email.shaw.ca.. .
I'm familiar with get and set function paradigms from Java, but what's
the recommended design for such in C++? Should it be like so:

foo& getFoo();
void setFoo(foo& f);

or like so:

foo& foo();
const foo& foo() const;

or some combination of the above?


When getters/setters are really needed I prefer the first form (with const
getters and const references for setters and getters) for one simple reason.
Setters are not always as simple as just assigning a given value to a member
variable, and if they are, they will not always remain so forever. Now, if
you allow a user of your class to modify a member variable through a
reference, you will have some problem when a setter must do more than just a
simple assignment. You will either break existing code or you have to invent
some new classes to pass an assignment in the client's code through your
setter.

Also, a setter (one which takes an argument and returns nothing except
success, perhaps) can be used for only one thing - to modify the state of an
object in a well defined way. A function returning a non-const reference to
a member variable, however, may be abused in many ways.

HTH
Heinz
Jul 23 '05 #13
> My preference is:

class C{
int x() { return _x; }
void x(int x_) { _x = x_; }
private:
int _x;

};

But I believe I am not in the majority on this.


That's what they seem to use in the ACE libaries.
(http://www.cs.wustl.edu/~schmidt/ACE.html)

It's not the best, of course, since it's somewhat ambiguous about whats
actually inferred by the statement.

If you're feeling brave you might want to check out STLSoft's
techniques for efficient properties for C++ (look for field properties
and method properties; http://www.stlsoft.org). It's described in the
Properties chapter in Mathew Wilson's Imperfect C++ book. As he admist
in the book, the technique's pretty funky, but he manages to get 100%
speed efficiency, and one byte per class space efficiency. Although
it's a bit challenging to look at, it works a treat - I used it in a
code generator at work - from COM typelibs to C++ wrapper classes -
with 'normal' COM property syntax.

If you're using Borland or Visual C++, you might want to check out
their compiler extensions. They support (what Wilson calls) "Method
Properties", where accessing the property calls a getter or a setter
method. As he points out, they don't support static properties, i.e.
properties for a class rather than an instance, or "Field Properties",
where read-only or write-only access is provided to an instance. If
you're using a different compiler, or want more flexibility, check out
the STLSoft templates.

HTH

The Raver

Jul 23 '05 #14


Victor Bazarov wrote:
Steven T. Hatton wrote:
E. Robert Tisdale wrote:
[...]
Yes. The get and set prefixes are superfluous.


So I'm the only one, eh?

No, of course not. You're in good company.

Our coding standard at work mandates the prefixes (actually "Get" and
"Set").

Brian

Jul 23 '05 #15
Default User wrote:
Victor Bazarov wrote:
Steven T. Hatton wrote:
E. Robert Tisdale wrote:

[...]
Yes. The get and set prefixes are superfluous.

So I'm the only one, eh?


No, of course not. You're in good company.


Our coding standard at work mandates the prefixes
(actually "Get" and "Set").


My condolences.
Jul 23 '05 #16
Heinz Ozwirk wrote:
"kelvSYC" <ke*****@no.email.shaw.ca> schrieb im Newsbeitrag
news:200620051552452355%ke*****@no.email.shaw.ca.. .
I'm familiar with get and set function paradigms from Java, but what's
the recommended design for such in C++? Should it be like so:

foo& getFoo();
void setFoo(foo& f);

or like so:

foo& foo();
const foo& foo() const;

or some combination of the above?


When getters/setters are really needed I prefer the first form (with const
getters and const references for setters and getters) for one simple
reason. Setters are not always as simple as just assigning a given value
to a member variable, and if they are, they will not always remain so
forever. Now, if you allow a user of your class to modify a member
variable through a reference, you will have some problem when a setter
must do more than just a simple assignment. You will either break existing
code or you have to invent some new classes to pass an assignment in the
client's code through your setter.

Also, a setter (one which takes an argument and returns nothing except
success, perhaps) can be used for only one thing - to modify the state of
an object in a well defined way. A function returning a non-const
reference to a member variable, however, may be abused in many ways.

HTH
Heinz


As a general rule, I agree on the constness arguments you've presented.
There may be reasonable places to make exceptions. For example, if you
were constructing some kind of composite data structure such as a binary
tree. Setting the leftChild might reasonably argue for an immediate
modifieable access to the left child. In that case, you may want to return
a non-const reference to the member even with the mutator (set) function.

OTOH your point about exposing the internal structure of the class by
returning a reference to its members is well taken. The more you expose of
the internal structure of a class, the less flexibility you have for future
modifications.

One advantage to maintaining all members as private (or protected - at a
cost) that is not often considered in C++ discussions, but is central to
Java design is the idea of being able to bind, constrain and synchronize
objects and/or their members. This extends the concept of invariance to
composite patterns, and facilitates implementing multithreading. Simply
put, it enables the program to detect and react to attempts at modifying
member data.

The reason protected members come at a cost is that protection allows a
derived class to circumvent the access checks implemented in the baseclass.

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #17


E. Robert Tisdale wrote:
Default User wrote:

Our coding standard at work mandates the prefixes
(actually "Get" and "Set").


My condolences.

Get lost, Trollsdale. Basically, if you're against something, I'll
assume it's good.

Brian

Jul 23 '05 #18
Default User wrote:


E. Robert Tisdale wrote:
Default User wrote:

> Our coding standard at work mandates the prefixes
> (actually "Get" and "Set").


My condolences.

Get lost, Trollsdale. Basically, if you're against something, I'll
assume it's good.


Personal attacks are off topic in c.l.c++. Please restrict such comments to
private communications.

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #19
On 2005-06-21 01:58:32 +0100, "E. Robert Tisdale"
<E.**************@jpl.nasa.gov> said:
Don't write
class XXX {
private:
That's redundant.

So what?


Just added noise, clutter, etc... that doesn't contribute to
clarity.
This private/protected/public business
is one of the most baffling, useless,
ill thought of, over abused contribution of C++.


Does that mean that you are prepared
to propose an alternative contribution?


Oh yes! And quite an involed one, you see :-)

Everything is a 'struct' with *every single member* public,
without even needing that "public:" keyword non-sense.

If you truly want to conceal members, use the Pimp idiom.
A public "Pimp" will just give no clue as to _how_ it does
things.

From fully opaque ("private") to fully transparent ("public")
there's a whole continuum that the 3.5 C++ keywords cannot do
justice to.

And their use is just a hindrance to eveloution, simply because
you *cannot* have the foresight, at design time, of what _really_
out to be this or that level of transparency.

If you make everything public, then you will be less tempted
to populate your classes with tons of (most often useless) members,
and will push the truly needed ones that you positively don't want
anyone to mess up with to the PImp side.
"I invented the term Object-Oriented,
and I can tell you I did not have C++ in mind."
- Alan Kay


But Alan Kay says nearly the same thing about Java.


True.
--
JFB

Jul 23 '05 #20
verec wrote:
[...]
If you make everything public, then you will be less tempted
to populate your classes with tons of (most often useless) members,
and will push the truly needed ones that you positively don't want
anyone to mess up with to the PImp side.
[...]


Yeah, right! Tell it to the people whose code I am now maintaining.

V
Jul 23 '05 #21
On 2005-06-21 22:22:05 +0100, Victor Bazarov <v.********@comAcast.net> said:
verec wrote:
[...]
If you make everything public, then you will be less tempted
to populate your classes with tons of (most often useless) members,
and will push the truly needed ones that you positively don't want
anyone to mess up with to the PImp side.
[...]


Yeah, right! Tell it to the people whose code I am now maintaining.


For anything you want to succeed at, there's one core psychological
trait you must exhibit: discipline.

If the people whose code you are maintaing didn't have any, tough luck!
:-(

But the failure of my neighbour is no encouragement to mine! :-)
--
JFB

Jul 23 '05 #22
E. Robert Tisdale wrote:
verec wrote:
You don't need getters/setters.
Accept the bare truth!

Don't write
class XXX {
private:
That's redundant.
So what?
Don't write
class XXX {
public:
That's stupid
write
struct XXX {
and you're done.

This private/protected/public business
is one of the most baffling, useless,
ill thought of, over abused contribution of C++.


Does that mean that you are prepared
to propose an alternative contribution?
"I invented the term Object-Oriented,
and I can tell you I did not have C++ in mind."

- Alan Kay
But Alan Kay says nearly the same thing about Java.
So what *did* Alan Kay have in mind
when he coined the term "object oriented"?
Smalltalk.
Alan Kay coined the term "object oriented"
to help describe his new computer programming language
and *not* to classify computer programming languages.
Other people used the term to classify programming languages
including the inventors of Simula
which, according to Alan Kay, "inspired" Smalltalk.


This is what the late Ole-Johan Dahl had to say about C++ and access to
class member data, with a bit of background:

<quote article="The Birth of Object Orientation: the Simula Languages"
url="http://heim.ifi.uio.no/~olejohan/">
It was decided at an early stage that our language should be based on a well
known one. Algol 60 was chosen for the following main reasons:
* the block structure,
* good programming security,
* European patriotism.
We realised that in order to profit from block structure in simulation
models it would be necessary to break out of the strict LIFO regime of
block instances in Algol. Thus, a new storage management system was
developed based on a list structured free store, [3]. Then a useful
simulation language could be defined by adding a few special purpose
mechanisms to Algol 60:
*A procedure-like activity declaration giving rise to so called
"processes".
Processes could range from record-like data structures to block structured
programs executing in a coroutine-like fashion, [35], [9], over a simulated
system time.
*Explicit process pointers for dynamic naming and referencing. (The
pointers were indirect through list forming "element" records.)
*A mechanism for accessing, from the outside, quantities local to the
outermost block level of processes, designed so that the access security
inherent in Algol would be maintained (the inspect construct).
*A few run time mechanisms for the scheduling and sequencing of processes
in system time, such as hold(: : :), suspending the calling process for a
specifed amount of system time.
</quote>

Note in particular the penultimate point above. Also note the use of the
term "objects" in the following:

<quote article="The Birth of Object Orientation: the Simula Languages">
The most important new concept of Simula 67 is surely the idea of data
structures with associated operators (and with or without own actions),
called *objects*. There is an important difference, except in trivial
cases, between
*/the inside view/ of an object, understood in terms of local variables,
possibly initialising operations establishing an invariant, and implemented
procedures operating on the variables maintaining the invariant, and
*/the outside view/, as presented by the remotely accessible procedures,
including some generating mechanism, dealing with more "abstract" entities.
....
Bjarne Stroustrup extended the Unix-related language C with several
Simula-inspired mechanisms. The language, called C++, has been much
used and has contributed importantly to the dissemination of the OO
ideas, [33]. Since C is fairly close to machine code, security aspects
are not the best. As a result, complex systems may be dificult to
implement correctly. C++ has been revised and extended, e.g. by multiple
inheritance.
</quote>

And finally note the above comment regarding the perceived _lack_ of
security in C/C++. From context it is clear this means that Dr. Dahl
perceived C++'s object member data to be insufficiently protected.

I'd say Dr. Dahl has precedence over Alan Kay regarding the use and
definition of "object" in the field of computer programming.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #23
Steven T. Hatton wrote:
I'd say Dr. Dahl has precedence over Alan Kay regarding the use and
definition of "object" in the field of computer programming.


I don't know who first used the term "object"
in the context of computer programming
but I'm sure that it was already ancient
when Dr. Dahl used it to help describe Simula.
It's the phrase "object oriented" which was coined by Alan Kay.
Nobody, including Alan Kay, is really sure what he meant.
Anyway, what Alan Kay had in mind was *messaging*.
Perhaps, if he had coined the tern "message oriented" instead,
we would all be talking about Message Oriented Programming (MOP)
instead of Object Oriented Programming (OOP). ;-)
Jul 23 '05 #24
E. Robert Tisdale wrote:
Steven T. Hatton wrote:
I'd say Dr. Dahl has precedence over Alan Kay regarding the use and
definition of "object" in the field of computer programming.


I don't know who first used the term "object"
in the context of computer programming
but I'm sure that it was already ancient
when Dr. Dahl used it to help describe Simula.
It's the phrase "object oriented" which was coined by Alan Kay.
Nobody, including Alan Kay, is really sure what he meant.
Anyway, what Alan Kay had in mind was *messaging*.
Perhaps, if he had coined the tern "message oriented" instead,
we would all be talking about Message Oriented Programming (MOP)
instead of Object Oriented Programming (OOP). ;-)


I don't know if the word "object" is a keyword in Simula, but that was the
impression I had. In so much as it was used to identify a construct with
internal data accessible only through functions, and associated functions
to operate on the data, I would say the first application of the word
"object" to what are now called objects in OO terms (class type objects in
C++) was when such constructs were first invented, i.e., in Simula.

There is a design approach that is related to OO called client/server. This
is somewhat distinct from the concept of client/server databases, etc. The
idea is that every object acts as a little computer holding its own data
(memory) and providing its own internal functions (cpu). Some objects
request services from others. The requester is called a client, and the
provider is called a server. It can also be the case that a client is also
a server. That is, some object requests services from a third object's
client, or from an object which it also provides services to.

In general OO lexicon member functions are often called
"methods" (Stroustrup reserves the term method for pure virtual funcitons),
and method invocations are called "messages". Sometimes models of this
sort are useful, and sometimes they are quite confusing.

The notion of inter-object communication is certainly useful in GUI code.
C++ culture seems to distinguish between 'signals' and 'events'. Signals
are lightweight calls that pass simple data such as an int or a string.
Events are complex objects that carry more complex data such as the
position and state of a mouse when a button was pressed, or released.

I don't see any contradiction between the notion of messaging and the
concept of controlled access to internal object data. I wonder what bee is
in Kay's bonnet that would make him deride C++ (if he actually did).

--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #25
Steven T. Hatton wrote:
I don't know if the word "object" is a keyword in Simula
but that was the impression I had.
In so much as it was used to identify a construct
with internal data accessible only through functions
and associated functions to operate on the data.
You have just described an Abstract Data Type (ADT).
All of the C++ built-in types fit your description.
A class is just a User Defined Type (UDT)
which Simula inherited from Algol's record structures.
I would say [that] the first application of the word "object"
to what are now called objects in OO terms (class type objects in C++)
was when such constructs were first invented, i.e., in Simula.
I think that the term 'object'
has always been used as a reference to an instance of some type
but I don't have access to all of the ancient [before 1967] texts.
There is a design approach that is related to OO called client/server.
This is somewhat distinct from the concept of client/server databases, etc.
The idea is that every object acts as a little computer
holding its own data (memory) and providing its own internal functions (cpu).
I never understood just what Alan Kay had in mind
but his work on [message] oriented computing roughly coincides
with the connection machine.
I think that he envisioned lightweight processes (objects)
communicating with each other by actually passing messages.
Unfortunately, the connection machine went extinct
before Kay's vision was realized.
Some objects request services from others.
The requester is called a client and the provider is called a server.
It can also be the case that a client is also a server.
That is, some object requests services from a third object's client
or from an object which it also provides services to.

In general OO lexicon member functions are often called "methods"
(Stroustrup reserves the term method for pure virtual funcitons),
and method invocations are called "messages".
Sometimes models of this sort are useful, and sometimes they are quite confusing.
We write programs for Beowulf clusters using
the Message Passing Interface (MPI) standard
so I never use Alan Kay's notion of messaging
because it tends to create confusion.
The notion of inter-object communication is certainly useful in GUI code.
C++ culture seems to distinguish between 'signals' and 'events'.
Signals are lightweight calls that pass simple data such as an int or a string.
Events are complex objects that carry more complex data such as the
position and state of a mouse when a button was pressed, or released.
Strictly speaking,
it is incorrect to use the terms 'signals' and 'events'
to reference the data (message)
implicit in the arrival of a signal or the occurrence of an event.
I don't see any contradiction between the notion of messaging and the
concept of controlled access to internal object data.
I wonder what bee is in Kay's bonnet
that would make him deride C++ (if he actually did).


I don't think that Alan Kay meant to "deride" C++ or Java.
He simply pointed out that they were *not* Smalltalk.
Jul 23 '05 #26
On 2005-06-22 01:08:14 +0100, "Steven T. Hatton"
<ch********@germania.sup> said:
And finally note the above comment regarding the perceived _lack_ of
security in C/C++. From context it is clear this means that Dr. Dahl
perceived C++'s object member data to be insufficiently protected.


Protection is one thing. Visibility another. Those public: private:
protected: (and friend) keywords in C++ have nothing to do with
protection.

Whereas, in Java, which uses the exact same keywords (minus friend and
plus package) they define a _protection_ level. There is absolutely no
way, while staying in Java, to access a *protected* member. To violate
this protection, you _have to_ write JNI code to subvert the type
system, and even then, that's far from easy, whereas in C++, access
to *protected* data, no matter how well "hidden" by the _visibility_
keywords are just a cast away...

Not that, as a "visibility" construct, those Java keywords aren't any more
appealing than in C++, but at least, they do offer _protection_ that
C++ cannot.

And besides this, that was not really the point, was it? The very
concept of getters does have some interest, for example in Eiffel,
where the same construct allows access to an array element or a
function call, allowing the _implemeter_ to change his mind while
not affecting the caller.

If you took C++ and removed all the noise keywords (class, public,
virual, protected. friend, explicit, and other overloaded operators),
it would become a decent langauge without pretense, much more palatable
than C, still with as little _protection_, but a lot more expressive

Quote of the day :-)
"Perfection in design is not when there is nothing more to add,
but when there's nothing left to remove"
- Antoine de Saint Exupery

Given the crust accumulated over the past 20 years, C++ has a long
way to go ...
--
JFB

Jul 23 '05 #27
E. Robert Tisdale wrote:
Steven T. Hatton wrote:
I don't know if the word "object" is a keyword in Simula
but that was the impression I had.
In so much as it was used to identify a construct
with internal data accessible only through functions
and associated functions to operate on the data.


You have just described an Abstract Data Type (ADT).
All of the C++ built-in types fit your description.
A class is just a User Defined Type (UDT)
which Simula inherited from Algol's record structures.


I intended that the associated functions are part of the object, as they are
in SIMULA. My wording was based on Dahl's words to describe the same.
Abstract data types are just that; abstractions. What function do I need
to call in order to access the internal data of a C++ int? What internal
data does a C++ int hold? That is, as opposed to the value stored in the
immediate memory location to which the variable identifier is bound.

ADT is generally used as a designation for such constructs as lists, stacks,
queues, trees, etc. though in the purest sense it would be better to
understand abstract data types in terms similar to platonic ideal forms
applying to any data structure in the abstract. Ironically Sebesta's
_Concepts_of_Programming_Languages_ attributes the introduction of the
notion of ADTs to SIMULA 67. He also states the following:

10.2.2 User-Defined Abstract Data Type

"The concept of user-defined abstract data types is a relatively recent one.
A user-defined abstract data type should provide the same characteristics
provided by floating-point types[which he used as a motivating example]:
(1) a type definition that allows program units to declare variables of the
type, but which hides the representation of these variables, and(2) a set
of operations for manipulating objects of the type.

We now formally define an abstract data type, in the context of user-defined
types. An abstract data type is a data type that satisfies the following
two conditions:

1) The representation, or definition, of the type and the operations on the
objects of the type are described in a single syntactical unit.

2) The representation of objects of the type are hidden from the program
units that use the type, so that the only direct operations possible on
those objects are those provided in the type's definition.

....

10.4 SIMULA 67 Classes

The first language facilities for the direct support of data abstraction,
although incomplete by our definiont, appeared in the class construct in
SIMULA 67.

10.4.1 Encapsulation

A SIMULA 67 class definion is a template for a type. Instances of the class,
sometimes called class objects, are created dynamically at the request of
the user program and can be referenced only with pointer variables."

He does point out that member data in Simula 67 is not hidden. As I
understand it, data hiding was intended, but not feasible within the
existing context. They did, however, introduce an inspect function for
reading the data as something of a gentelman's agreement not to access the
data directly. Sebesta later mentions that SIMULA 67 introduced the concept
of inheritance:

"15.1 Object-Oriented programming
The concept of object-oriented programming has its roots in SIMULA 67 but
was more fully developed in the evolution of the Smalltalk language."

"Data-oriented programming focuses on abstract data types."

....

"One fundamental restriction of abstract data types is that, once defined,
they cannot be conveniently modified for slightly different applications.
There is also no way to collect the common characteristics of families of
closely related types. Object-oriented programming languages extend data
abstraction with inheritance to provide these capabilities."

....

"Inheritance began in a limited form in SIMULA 67, whose classes can be
defined in hierarchies."
I have the second edition.

http://tinyurl.com/dcpgz

The same as the tinyurl:
http://btobsearch.barnesandnoble.com...21193628&itm=7
My use of the term ADT is more in harmony with this definition:

http://www.nist.gov/dads/HTML/abstractDataType.html

Which allows for the associated operation to be separate from the data
structure, and does not require data hiding. For example a linked list in
C++ is a fully legitimate ADT.
I would say the first application of the word "object"
to what are now called objects in OO terms (class type objects in C++)
was when such constructs were first invented, i.e., in Simula.


I think that the term 'object'
has always been used as a reference to an instance of some type
but I don't have access to all of the ancient [before 1967] texts.


SIMULA "objects" (I now realize the keyword was /activity/) were analogous
to C struct types holding both member data, and pointers to functions, and
also a very weak concept of data protection manifested in the /inspect/
construct.
The notion of inter-object communication is certainly useful in GUI code.
C++ culture seems to distinguish between 'signals' and 'events'.
Signals are lightweight calls that pass simple data such as an int or a
string. Events are complex objects that carry more complex data such as
the position and state of a mouse when a button was pressed, or released.


Strictly speaking,
it is incorrect to use the terms 'signals' and 'events'
to reference the data (message)
implicit in the arrival of a signal or the occurrence of an event.


Not when you are talking about event objects. Identifying the actual
4-space event of a mouse click is one use of the term event. The term is
also meaningfully applied to event objects such as instances of MouseEvent
or StateChangedEvent classes, etc., used to store data describing the
event. But if you want to get technical, a 4-space event is a
dimensionless geometric object analogous to a 3-space point, so it is not
meaningful to talk about a mouse click event in such exact terms. Please
see my signature for further information.
I don't see any contradiction between the notion of messaging and the
concept of controlled access to internal object data.
I wonder what bee is in Kay's bonnet
that would make him deride C++ (if he actually did).


I don't think that Alan Kay meant to "deride" C++ or Java.
He simply pointed out that they were *not* Smalltalk.


I seriously doubt he meant to communicate any ill will. A similar thing
happened with Linus Torvalds and Andrew Tannenbaum. The got into a debate
over best practices in OS design, and people were describing it as an
acrimonious confrontation when by the accounts of the participants it was
nothing more than a discussion of differing design ideas.

I did learn one thing from the current discussion. Smalltalk does not have
any concept of data-hinding.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #28
Steven T. Hatton wrote:
My use of the term ADT is more in harmony with this definition:

http://www.nist.gov/dads/HTML/abstractDataType.html
This is also what I mean by ADT.
Which allows for the associated operation
to be separate from the data structure
and does not require data hiding.
For example a linked list in C++ is a fully legitimate ADT.


I don't think that you get it yet.
No *implementation* of an ADT is an ADT
because no implementation remains an abstraction.
A User Defined Type (UDT) might implement an ADT.

Your remarks appear to imply a supernatural connection
between objects and the "methods" that may be applied to them.
Objects do *not* [normally] "contain" methods.
People who say such things are simply confused.
An object *may* contain a reference (pointer)
to a [virtual] function table (jump table)
which implements some or all of the methods.
These tables contain only pointers to "callback" functions
which are "registered" with the *class* when it is defined.
Every instance of the class and it's descendants
contains a reference to the corresponding jump table
but *never* the methods themselves.

You can, of course, use inheritance
to describe relationships between ADTs
but inheritance necessarily has a narrower, special meaning
when applied to UDTs in the context of a computer programming language.
Jul 23 '05 #29
> Protection is one thing. Visibility another. Those public: private:
protected: (and friend) keywords in C++ have nothing to do with
protection.
[]
If you took C++ and removed all the noise keywords (class, public,
virual, protected. friend, explicit, and other overloaded operators),
it would become a decent langauge without pretense, much more palatable
than C, still with as little _protection_, but a lot more expressive


I think I know what you mean, but I do not agree a 100%. I think those
"noise" keywords do give you some kind of protection. And "virtual" is
a distinct language feature. It doesn't provide you with anything that
would be extremely complex to do in C, but I consider it useful. The
virtual inheritance part less, but surely the virtual and pure
virtual functions.

I think the biggest benefit of having "private" and "protected" around
it that it catches a lot of mistakes people would make because they
just don't think enough. The kind of people who don't want to do
anything that might cause problems, but just don't care to read
documentations or just don't see why it would be a bad idea to do
certain things they are told not to do. People who get scared when
they read a reinterpret_cast, but wouldn't hesitate for a second to
write some values in some of your private structs in your C code,
just because the declaration is visible to them and they think "oh,
it will just do what I want, so why shouldn't I?".

(For the same reason I don't like Java and C# too much - they just
give the wrong people the wrong impression that they don't have to
care about certain things anymore. GC being the best example.)

I'm not saying those people should necessarily work as C++ programmers,
but reality is that they do. And reality is also that I can't stop
them from doing. Short: I do like "private:" and "protected:".
And I do write things like:

class FooManchoo
{
public:
void Lala();
//...
private:
unsigned m_sizeOfFooManchoosUnderpants;
//...
};

and I do so for 2 reasons. First it stops people from wondering or
asking me why I wrote "struct" and didn't write "class" instead, and
second because I prefer explicit ("public:") over implicit
information (just "struct", no "public:") in this situation.

Of course the level of "noise" that's right for someone is very
subjective - some people actually like to read/write "do begin"
and "then" and stuff. Some people don't, and some people don't
like to read/write "public:" and "private:". But I wouldn't go
as far as to say it's stupid or generally a bad idea to do either
way.

Bye,
Paul
Jul 23 '05 #30
verec wrote:
On 2005-06-22 01:08:14 +0100, "Steven T. Hatton"
<ch********@germania.sup> said:
And finally note the above comment regarding the perceived _lack_ of
security in C/C++. From context it is clear this means that Dr. Dahl
perceived C++'s object member data to be insufficiently protected.


Protection is one thing. Visibility another. Those public: private:
protected: (and friend) keywords in C++ have nothing to do with
protection.

Whereas, in Java, which uses the exact same keywords (minus friend and
plus package) they define a _protection_ level. There is absolutely no
way, while staying in Java, to access a *protected* member. To violate
this protection, you _have to_ write JNI code to subvert the type
system, and even then, that's far from easy, whereas in C++, access
to *protected* data, no matter how well "hidden" by the _visibility_
keywords are just a cast away...

Not that, as a "visibility" construct, those Java keywords aren't any more
appealing than in C++, but at least, they do offer _protection_ that
C++ cannot.

And besides this, that was not really the point, was it? The very
concept of getters does have some interest, for example in Eiffel,
where the same construct allows access to an array element or a
function call, allowing the _implemeter_ to change his mind while
not affecting the caller.

If you took C++ and removed all the noise keywords (class, public,
virual, protected. friend, explicit, and other overloaded operators),
it would become a decent langauge without pretense, much more palatable
than C, still with as little _protection_, but a lot more expressive

Quote of the day :-)
"Perfection in design is not when there is nothing more to add,
but when there's nothing left to remove"
- Antoine de Saint Exupery

Given the crust accumulated over the past 20 years, C++ has a long
way to go ...
--
JFB


Thanks for the newsflash. It's really a matter of perspective. There are
some problems with C++, but you have not identified any those I am aware
of. What you are criticizing are design choices made with a conscious
understanding of the tradeoffs. Many of the features you are criticizing
are the ones that C++ programmers find most attractive about the language.
I probably have more appreciation for Java than most of the people
participating in this newsgroup, but your points are lost on me.

Some people think C++ has advantages over Java when it comes to implementing
the core essentials of their application:

#ifdef USE_PRAGMA_IDENT_HDR
#pragma ident "@(#)ciObject.hpp 1.16 03/12/23 16:39:37 JVM"
#endif
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/

// ciObject
//
// This class represents an oop in the HotSpot virtual machine.
// Its subclasses are structured in a hierarchy which mirrors
// an aggregate of the VM's oop and klass hierarchies (see
// oopHierarchy.hpp). Each instance of ciObject holds a handle
// to a corresponding oop on the VM side and provides routines
// for accessing the information in its oop. By using the ciObject
// hierarchy for accessing oops in the VM, the compiler ensures
// that it is safe with respect to garbage collection; that is,
// GC and compilation can proceed independently without
// interference.
//
// Within the VM, the oop and klass hierarchies are separate.
// The compiler interface does not preserve this separation --
// the distinction between `klassOop' and `Klass' are not
// reflected in the interface and instead the Klass hierarchy
// is directly modeled as the subclasses of ciKlass.
class ciObject : public ResourceObj {
CI_PACKAGE_ACCESS
friend class ciEnv;
friend class DebugInformationRecorder;

private:
// A JNI handle referring to an oop in the VM. This
// handle may, in a small set of cases, correctly be NULL.
jobject _handle;
ciKlass* _klass;
uint _ident;

enum { FLAG_BITS = 1};
enum {
PERM_FLAG = 1
};
protected:
ciObject();
ciObject(oop o);
ciObject(Handle h);
ciObject(ciKlass* klass);

jobject handle() const { return _handle; }
// Get the VM oop that this object holds.
oop ciObject::get_oop() const {
assert(_handle != NULL, "null oop");
return JNIHandles::resolve_non_null(_handle);
}

bool is_perm() { return (_ident & PERM_FLAG) != 0; }
void set_perm() {
_ident |= PERM_FLAG;
}

// Virtual behavior of the print() method.
virtual void print_impl() {}

virtual const char* type_string() { return "ciObject"; }

void set_ident(uint id);
public:
// The klass of this ciObject.
ciKlass* klass();

// A number unique to this object.
uint ident();

// Are two ciObjects equal?
bool equals(ciObject* obj);

// A hash value for the convenience of compilers.
int hash();

// Tells if this oop has an encoding. (I.e., is it null or perm?)
// If it does not have an encoding, the compiler is responsible for
// making other arrangements for dealing with the oop.
// See ciEnv::make_perm_array
bool has_encoding();

// The address which the compiler should embed into the
// generated code to represent this oop. This address
// is not the true address of the oop -- it will get patched
// during nmethod creation.
//
// Usage note: no address arithmetic allowed. Oop must
// be registered with the oopRecorder.
jobject encoding();

// What kind of ciObject is this?
virtual bool is_null_object() const { return false; }
virtual bool is_instance() { return false; }
virtual bool is_method() { return false; }
virtual bool is_method_data() { return false; }
virtual bool is_array() { return false; }
virtual bool is_obj_array() { return false; }
virtual bool is_type_array() { return false; }
virtual bool is_symbol() { return false; }
virtual bool is_type() { return false; }
virtual bool is_return_address() { return false; }
virtual bool is_klass() { return false; }
virtual bool is_instance_klass() { return false; }
virtual bool is_method_klass() { return false; }
virtual bool is_array_klass() { return false; }
virtual bool is_obj_array_klass() { return false; }
virtual bool is_type_array_klass() { return false; }
virtual bool is_symbol_klass() { return false; }
virtual bool is_klass_klass() { return false; }
virtual bool is_instance_klass_klass() { return false; }
virtual bool is_array_klass_klass() { return false; }
virtual bool is_obj_array_klass_klass() { return false; }
virtual bool is_type_array_klass_klass() { return false; }

// Is this a type or value which has no associated class?
// It is true of primitive types and null objects.
virtual bool is_classless() const { return false; }

// Is this ciObject a Java Language Object? That is,
// is the ciObject an instance or an array
virtual bool is_java_object() { return false; }

// Does this ciObject represent a Java Language class?
// That is, is the ciObject an instanceKlass or arrayKlass?
virtual bool is_java_klass() { return false; }

// Is this ciObject the ciInstanceKlass representing
// java.lang.Object()?
virtual bool is_java_lang_Object() { return false; }

// Does this ciObject refer to a real oop in the VM?
//
// Note: some ciObjects refer to oops which have yet to be
// created. We refer to these as "unloaded". Specifically,
// there are unloaded ciMethods, ciObjArrayKlasses, and
// ciInstanceKlasses. By convention the ciNullObject is
// considered loaded, and primitive types are considered loaded.
bool is_loaded() const {
return handle() != NULL || is_classless();
}

// Subclass casting with assertions.
ciNullObject* as_null_object() {
assert(is_null_object(), "bad cast");
return (ciNullObject*)this;
}
ciInstance* as_instance() {
assert(is_instance(), "bad cast");
return (ciInstance*)this;
}
ciMethod* as_method() {
assert(is_method(), "bad cast");
return (ciMethod*)this;
}
ciMethodData* as_method_data() {
assert(is_method_data(), "bad cast");
return (ciMethodData*)this;
}
ciArray* as_array() {
assert(is_array(), "bad cast");
return (ciArray*)this;
}
ciObjArray* as_obj_array() {
assert(is_obj_array(), "bad cast");
return (ciObjArray*)this;
}
ciTypeArray* as_type_array() {
assert(is_type_array(), "bad cast");
return (ciTypeArray*)this;
}
ciSymbol* as_symbol() {
assert(is_symbol(), "bad cast");
return (ciSymbol*)this;
}
ciType* as_type() {
assert(is_type(), "bad cast");
return (ciType*)this;
}
ciReturnAddress* as_return_address() {
assert(is_return_address(), "bad cast");
return (ciReturnAddress*)this;
}
ciKlass* as_klass() {
assert(is_klass(), "bad cast");
return (ciKlass*)this;
}
ciInstanceKlass* as_instance_klass() {
assert(is_instance_klass(), "bad cast");
return (ciInstanceKlass*)this;
}
ciMethodKlass* as_method_klass() {
assert(is_method_klass(), "bad cast");
return (ciMethodKlass*)this;
}
ciArrayKlass* as_array_klass() {
assert(is_array_klass(), "bad cast");
return (ciArrayKlass*)this;
}
ciObjArrayKlass* as_obj_array_klass() {
assert(is_obj_array_klass(), "bad cast");
return (ciObjArrayKlass*)this;
}
ciTypeArrayKlass* as_type_array_klass() {
assert(is_type_array_klass(), "bad cast");
return (ciTypeArrayKlass*)this;
}
ciSymbolKlass* as_symbol_klass() {
assert(is_symbol_klass(), "bad cast");
return (ciSymbolKlass*)this;
}
ciKlassKlass* as_klass_klass() {
assert(is_klass_klass(), "bad cast");
return (ciKlassKlass*)this;
}
ciInstanceKlassKlass* as_instance_klass_klass() {
assert(is_instance_klass_klass(), "bad cast");
return (ciInstanceKlassKlass*)this;
}
ciArrayKlassKlass* as_array_klass_klass() {
assert(is_array_klass_klass(), "bad cast");
return (ciArrayKlassKlass*)this;
}
ciObjArrayKlassKlass* as_obj_array_klass_klass() {
assert(is_obj_array_klass_klass(), "bad cast");
return (ciObjArrayKlassKlass*)this;
}
ciTypeArrayKlassKlass* as_type_array_klass_klass() {
assert(is_type_array_klass_klass(), "bad cast");
return (ciTypeArrayKlassKlass*)this;
}

// Print debugging output about this ciObject.
void print();

// Print debugging output about the oop this ciObject represents.
void print_oop();
};
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #31
E. Robert Tisdale wrote:
Steven T. Hatton wrote:
My use of the term ADT is more in harmony with this definition:

http://www.nist.gov/dads/HTML/abstractDataType.html
This is also what I mean by ADT.
Which allows for the associated operation
to be separate from the data structure
and does not require data hiding.
For example a linked list in C++ is a fully legitimate ADT.


I don't think that you get it yet.
No *implementation* of an ADT is an ADT
because no implementation remains an abstraction.
A User Defined Type (UDT) might implement an ADT.


The linked list in (I meant to type C, not C++) C is conceptually derived
from the ADT called linked list. In C++ terminology derivation is an is_a
relationship.
Your remarks appear to imply a supernatural connection
between objects and the "methods" that may be applied to them.
Objects do *not* [normally] "contain" methods.
If I follow Stroustrup's usage of the term method, methods are never
manifest as addressable entities. The is_a relationship does not apply to
member functions because they are not inherited, they are overridden. If
you find a way to invoke a pure virtual member function on a C++ object,
please let the rest of us know.
People who say such things are simply confused.
Either that or they are speaking in terms of conceptual abstractions which
they assume the audience understands. Furthermore, the whole concept of
"containment" in computer programming is metaphorical and inexact except
when a clear, restrictive definition is provided for the context. I never
suggested that a function would actually be present within the physical
representation of the instance of a class type variable. The most I
suggested, for the sake of analogy is that SIMULA's classes might be
thought of as similar to C structs with member data and member pointers to
functions. I was really thinking in terms of language syntax, but now that
I think about it, functional closures might be a better analog.

In C++ many compilers have traditionally converted C++ code into
"equivalent" C code, and then compiled the resulting C program. GCC for
one, no longer does that. Conceptually what a compiler will do with member
functions is to convert them to functions of a form similar to
ClassName::memberFunctionName(ClassName * _this, /*...*/); and treat it
like a non-member friend function with 'this' as the first argument.
Typically there will be some memory location designated as the beginning of
the class representation used by the processor to determine were to take
the offset from when accessing the actual opcode for the function. That
opcode is not usually immediately adjacent to the instance data. Exactly
how concrete class type objects are associated with their instance data is
not clear to me. In the case of classes with virtual functions there is a
virtual function table, but, again, I am not sure exactly what the vptr
actually holds. Is it an offset from the beginning of the segment, or a
relative address of the the vtbl, or something else?

What I've read is that the vptr points to the start of the vtbl, and there
is an offset for each internal sub-object with virtual functions, and each
internal subobject has a list of offsets to the beginning of the
instruction sequence for that function. Alternatively, each internal
sub-object with virtual member funcitons may maintain its own vtbl which
holds the address of any vtbl of its own sub-objects, if any. Objects of
pointer to member type represent offsets into the vtbl if the class has
virtual functions. Otherwise the pointer to member points directly to a
member of the class.
An object *may* contain a reference (pointer)
to a [virtual] function table (jump table)
which implements some or all of the methods.
These tables contain only pointers to "callback" functions
which are "registered" with the *class* when it is defined.
Every instance of the class and it's descendants
contains a reference to the corresponding jump table
but *never* the methods themselves.

You can, of course, use inheritance
to describe relationships between ADTs
but inheritance necessarily has a narrower, special meaning
when applied to UDTs in the context of a computer programming language.


It really depends on exactly what definition one uses for ADT. The
definition I suggested best corresponds to my own notion of ADTs is not the
same as that used by Sebesta nor by Lippman. Of course I do not try to
draw a carful distinction between the notion of UDT and ADT when discussing
general concepts of programming. UDT are user defined types. If these
happen to be of the category typically called ADTs "lists, queues, trees,
etc" I will use the term ADT.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell
Jul 23 '05 #32
Steven T. Hatton wrote:
If I follow Stroustrup's usage of the term method,
methods are never manifest as addressable entities.
The is_a relationship does not apply to member functions
because they are not inherited, they are overridden.
Just to clear up any possible confusion:

class Base {
private:
// representation
int I;
public:
// functions
int f(void) const { return I; }
int g(void) const { return I + 13; }
int h(void) const { return I + 42; }
// constructors
Base(int i = 0): I(i) { }
};

class Derived: public Base {
public:
// functions
int h(void) const { return f() + 33; }
};

Derived *inherits* f(void) and g(void) from Base
but h(void) is *overridden*.
If you find a way to invoke a pure virtual member function on a C++ object,
please let the rest of us know.
I don't know what you mean.
Furthermore, the whole concept of "containment" in computer programming
is metaphorical and inexact except when a clear, restrictive definition
is provided for the context.
I never suggested that a function would actually be present
within the physical representation of the instance of a class type variable.
Of course not.
But not all subscribers to the comp.lang.c++ newsgroup understand that
so I think that it is important to make this point clear.

What I've read is that the vptr points to the start of the vtbl
and there is an offset for each internal sub-object with virtual functions
and each internal subobject has a list of offsets to the beginning of the
instruction sequence for that function. Alternatively, each internal
sub-object with virtual member funcitons may maintain its own vtbl which
holds the address of any vtbl of its own sub-objects, if any.
Objects of pointer to member type represent offsets into the vtbl
if the class has virtual functions.
Otherwise the pointer to member points directly to a member of the class.


These are actually implementation details
but an accurate description of the "typical" implementation.

You can implement this in C as I have shown several times
in the comp.lang.c newsgroup and at least once in this newsgroup.
C is *not* an object oriented programming language
because it does not provide direct support for

1.) encapsulation (meaning data hiding),
2.) inheritance or
3.) run-time polymorphism.

but you can still write object-oriented programs in C --
it's just a little more tedious and less reliable.
Jul 23 '05 #33

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Wei Wang | last post: by
112 posts views Thread by mystilleef | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.