C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

To bean or not to bean
Goto page 1, 2, 3, 4, 5  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Steven T. Hatton
Guest





PostPosted: Sat Aug 28, 2004 8:39 am    Post subject: To bean or not to bean Reply with quote



Stroustrup's view on classes, for the most part, seems to be centered around
the notion of invariants. After a bit of adjusting to the use of yamt (yet
another math term) in computer science, I came to appreciate some of the
significance in what he is asserting. I believe a good example would be
the Riemann-Christoffel curvature tensor. In the 4-space of general
relativity, there are 256 components of this beast.

One approach to representing this tensor might be a struct with 256 float
members all public. The user simply treats it as a big bag of bits. This
tensor - by definition - has certain invariant properties which must remain
constant under certain groups of operations. That means that, either the
user must be carful to enforce the rules preserving the invariants if he is
going to modify the components directly. For this reason, it makes sense
to put the data in a class and only allow controlled access through the use
of invariant preserving access methods.

Stroustrup also argues that a reasonable test to determine if you really do
have a class with invariants is to ask if there are multiple
representations of the data structure which are functionally equivalent.
Indeed there are for this tensor. And that can actually buy you a lot.
Although the tensor has 256 components, only 20 are independent. That
means you can represent the tensor as an object of only 20 data members,
and if circumstances demand all 256 components be available in the program,
that can be accomplished by multiply indexing the storage locations through
access methods which collectively give the illusion that the entire tensor
exists with all of it's 256 components.

So far, so good. I pretty much agree with his reasoning for distinguishing
between what should properly be represented as a class with private (or
protected) data, as opposed to simply a struct with all public members and
direct user access. I like a lot of the careful discernment found in C++ as
opposed to Java, for example. There are not concepts of constness and
mutable caching in typical Java literature. That shows me C++ has
expressive powers that go well beyond other general purpose languages.

There is however, one point that Stroustrup doesn't address regarding
'accessor' methods. He tells us we should avoid writhing classes with
direct accessor methods to manipulate the data. The reasoning seems
obvious to me. If the user has a reason to micro-manage the data, it
probably doesn't have a clearly defined invariant that could and should be
preserved under the operations applied to it collectively.

The Java community operates with a different philosophy regarding data and
classes. Basically, nothing is public other than static constants, and
accessor methods. The simplest notion of a been in Java is just a class
with data members read and written through the mediation of 'set' and 'get'
methods. The payoff to this very protective approach to managing data is
that it facilitates such design features as event-listener patterns, and
concurrent programming. The access methods provide a natural means of
locking access to data, and also monitoring access for purposes of event
notification.

One of the more important developments in TC++PL(SE) is the creation of
abstract user interface components as a means of demonstrating the various
options for using inheritance and class hierarchies. Stroustrup argues -
correctly IMO - that a programmer should strive to solve problems
independently of the proprietary libraries he may be developing with.

This is what I have been calling an AUI (abstract user interface) for a few
years. I decided I would try the exercise as part of a project I'm working
on with the goal of visually representing the various access patterens use
to simulate multidimensional arrays using valarray, slices, and gslices.
The program creates a tree of grid cell objects which become the elements
of the graphical representation of the multidimensional matrix.

I created an interface class with all pure virtual functions, and one data
member. The data member is an object that holds default values to be
shared among the different grid elements. This may seem somewhat
convoluted, but it enables me to do some interesting things, such as change
the value of the default values object, notify all the grid cell objects
which own a DefaultBox that their defaults have been changed, and they need
to consider updating.

That demonstrates what I was getting at regarding the use of an
event/listener (observer) pattern to adapt to changes in a particular
object. There's something else that my design also seems to dictate.

The class used to default initialize grid cells is a good example of what
I'm finding appropriate for my design, and which seems to contradict
Stroustrup's recommendation to avoid 'set' and 'get' functions. That's
actually a pretty significant part of what my grid cell objects consist of.
That is, data members with read and mutate functions for the data.

#ifndef STHBOXDEFAULTS_H
#define STHBOXDEFAULTS_H
#include <string>

namespace sth
{
using std::string;
/**
@author Steven T. Hatton
*/
class BoxDefaults
{
public:
BoxDefaults( bool is_leaf_ = false,
bool is_vertical_ = false,
string text_ = "[...]",
RgbColor bg_color_ = RgbColor::YELLOW,
RgbColor text_color_ = RgbColor::BLACK,
RgbColor edge_color_ = RgbColor::RED,
double h_ = 35,
double w_ = 50,
double border_w_ = 5,
double x_ = 0,
double y_ = 0,
int bg_z_ = 1,
int text_z_ = 2
)
: is_leaf( is_leaf_ ),
is_vertical( is_vertical_ ),
text( text_ ),
bg_color( bg_color_ ),
text_color( text_color_ ),
edge_color( edge_color_ ),
h( h_ ),
w( w_ ),
border_w( border_w )
{}

virtual ~BoxDefaults(){}
/**
* Are child boxes layed out vertically?
*/
virtual bool Is_vertical() const
{
return this->is_vertical;
}

virtual void Is_vertical(const bool& is_vertical_)
{
this->is_vertical = is_vertical_;
}

/**
* Is this a leaf node?
*/
virtual bool Is_leaf() const
{
return this->is_leaf;
}

virtual void Is_leaf(const bool& is_leaf_)
{
this->is_leaf = is_leaf_;
}

virtual RgbColor Bg_color() const
{
return this->bg_color;
}

virtual void Bg_color(const RgbColor& bg_color_)
{
this->bg_color = bg_color_;
}
/* etc., etc. */

};
}

This seems rather natural to me, but it makes me a bit uneasy, because
Stroustrup has suggested it may not be a good design approach. I will not
that he also insists that his advice and opinions are not intended as
inviolable dictates, nor are they expected to be applicable equally in all
circumstances.

What is your opinion of the use of the 'Java Beans' design approach? I
realize there is more to a Bean than simply a class with data, events, and
associated listeners. Nonetheless, that seems to be the definitive essence
of what they areally are. There are some aspects of the JavaBean
specification that strike me as arcane and seem to offer far more potential
trouble than potential worth. I do believe the general approach is
something worth understanding, and considering for C++ design. Here's the
JavaBean spec:

http://java.sun.com/products/javabeans/docs/spec.html

What do you think of these ideas as potentially applicable to C++ code?
--
"[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I think
the time has come to be serious about macro-free C++ programming." - B. S.

Back to top
Bob Hairgrove
Guest





PostPosted: Sat Aug 28, 2004 10:34 am    Post subject: Re: To bean or not to bean Reply with quote



On Sat, 28 Aug 2004 04:39:31 -0400, "Steven T. Hatton"
<susudata (AT) setidava (DOT) kushan.aa> wrote:

[snip]
Quote:
So far, so good. I pretty much agree with his reasoning for distinguishing
between what should properly be represented as a class with private (or
protected) data, as opposed to simply a struct with all public members and
direct user access. I like a lot of the careful discernment found in C++ as
opposed to Java, for example. There are not concepts of constness and
mutable caching in typical Java literature. That shows me C++ has
expressive powers that go well beyond other general purpose languages.

<OT-advocacy-mode>
Every language should have its strong points which distinguish it from
other languages, giving it its reason for existence. I'll only say
that I like C++ because it allows the developer to be as much or as
little OOP as she likes. With Java, you are pretty much stuck with OOP
whether or not that is the appropriate tool for the task at hand.
</OT-advocacy-mode>

I'll snip the rest because I merely want to comment on your naming
style:

[snip]
Quote:
class BoxDefaults
{
public:
BoxDefaults( bool is_leaf_ = false,
bool is_vertical_ = false,
string text_ = "[...]",
RgbColor bg_color_ = RgbColor::YELLOW,
RgbColor text_color_ = RgbColor::BLACK,
RgbColor edge_color_ = RgbColor::RED,
double h_ = 35,
double w_ = 50,
double border_w_ = 5,
double x_ = 0,
double y_ = 0,
int bg_z_ = 1,
int text_z_ = 2
)
: is_leaf( is_leaf_ ),
is_vertical( is_vertical_ ),
text( text_ ),
bg_color( bg_color_ ),
text_color( text_color_ ),
edge_color( edge_color_ ),
h( h_ ),
w( w_ ),
border_w( border_w )
^^^^^^^^

Oops ... recursive initialization here!
This is why I do not like trailing underscores.

Also, what do you think of this:
: is_leaf ( is_leaf_ )
, is_vertical( is_vertical_ )
, text ( text_ )
, bg_color ( bg_color_ )
, text_color ( text_color_ )
, edge_color ( edge_color_ )
, h ( h_ )
, w ( w_ )
etc. as opposed to having the commas at the end? I find it much easier
to avoid superfluous comma errors like this because I don't have to
read to the end of the line to find it.

--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]

Back to top
Victor Bazarov
Guest





PostPosted: Sat Aug 28, 2004 2:14 pm    Post subject: Re: To bean or not to bean Reply with quote



"Bob Hairgrove" <invalid (AT) bigfoot (DOT) com> wrote...
Quote:
[..]
Also, what do you think of this:
: is_leaf ( is_leaf_ )
, is_vertical( is_vertical_ )
, text ( text_ )
, bg_color ( bg_color_ )
, text_color ( text_color_ )
, edge_color ( edge_color_ )
, h ( h_ )
, w ( w_ )
etc. as opposed to having the commas at the end? I find it much easier
to avoid superfluous comma errors like this because I don't have to
read to the end of the line to find it.

That's my choice as well (without the excessive spaces, though).
Makes adding things clearer, especially to the end, when otherwise
I usually forget to add the comma after the last initialiser.

V



Back to top
Steven T. Hatton
Guest





PostPosted: Sun Aug 29, 2004 1:18 am    Post subject: Re: To bean or not to bean Reply with quote

Bob Hairgrove wrote:

Quote:
On Sat, 28 Aug 2004 04:39:31 -0400, "Steven T. Hatton"
[email]susudata (AT) setidava (DOT) kushan.aa[/email]> wrote:

[snip]
So far, so good. I pretty much agree with his reasoning for
distinguishing between what should properly be represented as a class with
private (or protected) data, as opposed to simply a struct with all public
members and direct user access. I like a lot of the careful discernment
found in C++ as
opposed to Java, for example. There are not concepts of constness and
mutable caching in typical Java literature. That shows me C++ has
expressive powers that go well beyond other general purpose languages.

OT-advocacy-mode
Every language should have its strong points which distinguish it from
other languages, giving it its reason for existence. I'll only say
that I like C++ because it allows the developer to be as much or as
little OOP as she likes. With Java, you are pretty much stuck with OOP
whether or not that is the appropriate tool for the task at hand.
/OT-advocacy-mode

Somewhere out on the net there is a lexer "written in Java" that consists of
one class with all of the code written as member functions. The program is
virtually indistinguishable from C other than the use of the necessary
class to get the thing bootstrapped. I believe a lot of people are missing
the real significance of the design choice made by the Java designers that
requires all code to be in a class. It wasn't really done for the benefit
of the application programmer. It was done because it facilitates the
loading and execution of the program by the JVM.

To some extent, it is an artifact of the way the language is implemented.
If you think of the top level class as part of the execution environment,
you will understand there is far less difference between Java and C++ in
this regard than there otherwise may seem.

As you've suggested this is somewhat off topic. I'm discussing it here
because it provides a contrast to C++ that might serve to solidify
understanding, and lead to new approaches to programming in C++. I don't
believe Trolltech strove to emulate Java in developing their toolkit, but
there are some significant similarities in the way things are done in Qt.

Unlike Java, Qt does not restrict you from using namespace local
declarations, but it does encourage the design approach of putting
everything in some class, and treating your program as a collection of
interacting objects.

Note: what follows is pseudo-history:

Think of it like this. Originally programs were a long sequence of
instructions read in and executed one after the other. Some of these
instructions were able to tell the computer to goto and execute a
previously encountered instruction and to continue from there sequentially
as if the instruction had appeared after the branch point.

Then some guy decided goto was a four-letter-word, and advocated banishing
its use. The result was to hide goto instructions behind fancy constructs
such as function calls, and switch statements. Nonetheless, a program
remained a sequence of instructions to be executed as if the computer were
reading down a page, with the understanding that it may examine a
cross-reference at times. That is what C-style programming is.

At some point in the ancient past the notion of an eventloop was discovered.
The result was Emacs. Emacs later mated with C, resulting in several
offspring. Namely XEmacs, ECMAScript (JavaScript), (GNU)Emacs, Mozilla
etc. The person who facilitated this seemingly unnatural union of Lisp and
C was a man named James Gosling. This is the same James Gosling who
invented Java. Note that an interesting thing happened when these ideas
were merged. Some of the offspring are programs, and some are programming
languages. And some can't make up their mind which way they go.

At the same time as these offspring were being engendered and/or maturing a
more carfully arranged union between C and Simula was consummated. The
result was the highly cultured and demanding C++. C++ retains the original
sequential execution model inherited from C. C++ is a
*_programming_language_* not a program (damnit!) And that's the fundamental
difference between C++ and Java.

Quote:
border_w( border_w )
^^^^^^^^
Oops ... recursive initialization here!
This is why I do not like trailing underscores.

I dislike the entire member initialization facility in C++. As for trailing
underscores, I don't get stung like that very often. As long as I retain
consistency, it is easy to identify such errors. Note the code you are
critiquing was copied directly out of the edit buffer of a program under
development. I hadn't even completed the member initialization block. Any
system such as the use of trailing underscores is subject to error. The
only thing worse is to not have a system at all. The use of leading
underscores is actually reserved for the implementation, though a program
can define and use such identifiers without errors being generated,
provided there are not conflicts with the implementations use of the same.


Quote:
Also, what do you think of this:
: is_leaf ( is_leaf_ )
, is_vertical( is_vertical_ )
, text ( text_ )
, bg_color ( bg_color_ )
, text_color ( text_color_ )
, edge_color ( edge_color_ )
, h ( h_ )
, w ( w_ )
etc. as opposed to having the commas at the end?

I used to be a strong advocate of putting commas at the beginning of such
continued lines, but that was contrary to the culture in which I found
myself. I do like the style, and, after testing the auto-formatting in
KDevelop, and Emacs, I have discovered that both allign the code quite
nicely in the way you have shown above.

I also agree regarding the placement of the leading parentheses. I was
experimenting with the alternative because the long whitespace between the
identifier and the opening parenthesis also bothers me a bit. Your
approach is easier on the eye.

As for trailing underscores, what is your alternative?

Quote:
I find it much easier
to avoid superfluous comma errors like this because I don't have to
read to the end of the line to find it.

Agreed. What about situations such as:

bigLongLeftHandSide
= bigLongIdentifier
->bigLongMemberName
->yourGonnaWrapSucker
->bigLongFunctionName();
?

-- "[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I think
the time has come to be serious about macro-free C++ programming." - B. S.


Back to top
Steven T. Hatton
Guest





PostPosted: Sun Aug 29, 2004 1:28 am    Post subject: Re: To bean or not to bean Reply with quote

Victor Bazarov wrote:

Quote:
That's my choice as well (without the excessive spaces, though).
Makes adding things clearer, especially to the end, when otherwise
I usually forget to add the comma after the last initialiser.

V

For me, that trailing comma gone missing becomes quite obvious when I C-x
C-h C-M- the remaining line are shot off the right side of the page into
oblivion. Same with KDevelop.
-- "[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I think
the time has come to be serious about macro-free C++ programming." - B. S.


Back to top
Phlip
Guest





PostPosted: Sun Aug 29, 2004 2:03 am    Post subject: Re: To bean or not to bean Reply with quote

Steven T. Hatton wrote:

Quote:
Somewhere out on the net there is a lexer "written in Java" that consists
of
one class with all of the code written as member functions. The program
is
virtually indistinguishable from C other than the use of the necessary
class to get the thing bootstrapped. I believe a lot of people are
missing
the real significance of the design choice made by the Java designers that
requires all code to be in a class. It wasn't really done for the benefit
of the application programmer. It was done because it facilitates the
loading and execution of the program by the JVM.

You cannot legislate morality.

In Ruby, everything is a method. Ruby does not enforce this by beating the
programmer with syntax errors for their "heresy". Ruby enforces this by
helping. It provides a global object, and all statements execute within its
context. Because one cannot step outside this cosmological object,
everything in Ruby is inside an object, without syntax errors if you decline
to create an object.

(However, in Ruby, nothing will stop you from writing everything into one
long method... You cannot legislate morality. You can, however, legislate
immorality.)

Quote:
As you've suggested this is somewhat off topic. I'm discussing it here
because it provides a contrast to C++ that might serve to solidify
understanding, and lead to new approaches to programming in C++. I don't
believe Trolltech strove to emulate Java in developing their toolkit, but
there are some significant similarities in the way things are done in Qt.

F--- topicality. And Qt came first, right?

Quote:
-- "[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I
think
the time has come to be serious about macro-free C++ programming." - B. S.

The preprocessor rules.

--
Phlip
http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces




Back to top
E. Robert Tisdale
Guest





PostPosted: Sun Aug 29, 2004 2:42 am    Post subject: Re: To bean or not to bean Reply with quote

Steven T. Hatton wrote:

Quote:
Stroustrup's view on classes, for the most part, seems to be centered around
the notion of invariants. After a bit of adjusting to the use of yamt
(yet another math term) in computer science,
I came to appreciate some of the significance in what he is asserting.

Please site passage an verse.
You probably misunderstood what Stroustrup was saying.
There is nothing terribly profound in language design.
It is a mistake to read too much into what Stroustup says.
He really tries to explain his ideas in the most straight-forward manner
using *plain* English.

Quote:
I believe a good example would be the Riemann-Christoffel curvature tensor.

No, it isn't a good example.
Very few computer programmers have cause to truck with such things.

A C++ class (or struct) is used
to introduce a User Defined Type (UDT) into a program.
A C++ class is most useful in implementing an Abstract Data Type (ADT).
The reason for data hiding (private data members) is practical.
It allows the class library developer to change the data representation
without any changes to application programs which use the class library
except, possibly, recompiling the application program and linking in
the revised class library.

Back to top
Steven T. Hatton
Guest





PostPosted: Sun Aug 29, 2004 2:52 am    Post subject: Re: To bean or not to bean Reply with quote

Phlip wrote:

Quote:
F--- topicality. And Qt came first, right?

Qt development begain in 1991, and the first public release was on the 20th
of May, 1995. The same week as the first release of Java.

Quote:
The preprocessor rules.

The preprocessor is the main reason that there is no serious C++ contender
to the highly successful J2EE development platform. The Cpp, and the
techniques it supports do not scale to that level of programming.
Stroustrup has some opinions that I don't fully accept. AAMOF, my
intention in beginning this thread was to discuss one such opinion. In the
past, when I have taken a position contrary to his, I eventually came to
realize he was more correct than I originally thought. I can't imagine
anyone has a more extensive understanding of the relationship between C++
and the Cpp than he does. Why do you think he is wrong about it? (I can
only assume that was your intended meaning in saying "The preprocessor
rules".)

--
"[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I think
the time has come to be serious about macro-free C++ programming." - B. S.


Back to top
Phlip
Guest





PostPosted: Sun Aug 29, 2004 3:08 am    Post subject: Re: To bean or not to bean Reply with quote

Steven T. Hatton wrote:

Quote:
The preprocessor is the main reason that there is no serious C++ contender
to the highly successful J2EE development platform. The Cpp, and the
techniques it supports do not scale to that level of programming.
Stroustrup has some opinions that I don't fully accept. AAMOF, my
intention in beginning this thread was to discuss one such opinion. In
the
past, when I have taken a position contrary to his, I eventually came to
realize he was more correct than I originally thought. I can't imagine
anyone has a more extensive understanding of the relationship between C++
and the Cpp than he does. Why do you think he is wrong about it? (I can
only assume that was your intended meaning in saying "The preprocessor
rules".)

Use the Cpp for:

- token pasting
- stringerization
- conditional compilation (oh, yeah. Everyone likes that one...)

Putting those inside a C language would make it not a C language. And they
permit techniques that more "modern" languages need but can't do.

A repost:

Visual Studio surfs to errors using <F8>: Go To Output Window Next Location.
The Windows SDK function to write text into the output panel, for this
feature to read it and surf to an error, is OutputDebugString().
Putting them all together yields this killer trace macro:

#define db(x_) do { std::stringstream z;
z << __FILE__ << "(" << __LINE__ << ") : "
#x_ " = " << x_ << endl;
cout << z.str() << std::flush;
OutputDebugStringA(z.str().c_str());
} while (false)

That takes any argument, including expressions, which support operator<<. We
will return to these techniques while exploring more Fault Navigation issues
in C++.

db(q) pushes "C:pathsource.cpp(99) : q = 5n" into the Output Debug panel.
to the line containing the db(q).

Those are major wins. Tracing with db() is very low cost for very high
feedback.

C++ has flaws. But those of you inclined to dismiss it entirely are invited
to write db(), with all these features, in your favorite language.

--
Phlip
http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces



Back to top
Steven T. Hatton
Guest





PostPosted: Sun Aug 29, 2004 4:03 am    Post subject: Re: To bean or not to bean Reply with quote

E. Robert Tisdale wrote:

Quote:
Steven T. Hatton wrote:

Stroustrup's view on classes, for the most part, seems to be centered
around
the notion of invariants. After a bit of adjusting to the use of yamt
(yet another math term) in computer science,
I came to appreciate some of the significance in what he is asserting.

Please site passage an verse.
Regarding what? I'm not sure what you are questioning.


Quote:
You probably misunderstood what Stroustrup was saying.
There is nothing terribly profound in language design.
It is a mistake to read too much into what Stroustup says.
He really tries to explain his ideas in the most straight-forward manner
using *plain* English.

I believe a good example would be the Riemann-Christoffel curvature
tensor.

No, it isn't a good example.
Very few computer programmers have cause to truck with such things.

For my purposes, it was a good example. It is irrelevant whether a person
understand the full definition of the tensor. Only that it has invariants,
and that it has multiple data elements, some of which are redundant.

Quote:
A C++ class (or struct) is used
to introduce a User Defined Type (UDT) into a program.
A C++ class is most useful in implementing an Abstract Data Type (ADT).
The reason for data hiding (private data members) is practical.
It allows the class library developer to change the data representation
without any changes to application programs which use the class library
except, possibly, recompiling the application program and linking in
the revised class library.

I'm not sure how that really address my question. I am asking whether the
creation of a class that consists of data members which are all
manipulatable through the use of access funcitons is contrary to philosophy
that a class should have a clearly defined invariant that is preserved when
operated on by invoking its member functions, or friend functions.

More specifically, I am asking if the creation of a class that consists of
nothing but data fields and set and get methods is an indication that I am
doing something wrong.
--
"[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I think
the time has come to be serious about macro-free C++ programming." - B. S.


Back to top
Steven T. Hatton
Guest





PostPosted: Sun Aug 29, 2004 4:25 am    Post subject: Re: To bean or not to bean Reply with quote

Phlip wrote:

Quote:
Steven T. Hatton wrote:
I can't imagine
anyone has a more extensive understanding of the relationship between C++
and the Cpp than he does. Why do you think he is wrong about it?

Use the Cpp for:

- token pasting
Why? What can that give me that I cannot achieve using the internal

features of the language?

Quote:
- stringerization

I'm not familiar with the term. Care to explain?

Quote:
- conditional compilation (oh, yeah. Everyone likes that one...)

I am aware that the Cpp is used for this. There have, as yet, been no
viable alternatives introduced, and accepted into the C++ standard.

Quote:
Putting those inside a C language would make it not a C language. And they
permit techniques that more "modern" languages need but can't do.

A repost:

Visual Studio surfs to errors using <F8>: Go To Output Window Next
Location. The Windows SDK function to write text into the output panel,
for this feature to read it and surf to an error, is OutputDebugString().
Putting them all together yields this killer trace macro:

#define db(x_) do { std::stringstream z;
z << __FILE__ << "(" << __LINE__ << ") : "
#x_ " = " << x_ << endl;
cout << z.str() << std::flush;
OutputDebugStringA(z.str().c_str());
} while (false)

That takes any argument, including expressions, which support operator<<.
We will return to these techniques while exploring more Fault Navigation
issues in C++.

db(q) pushes "C:pathsource.cpp(99) : q = 5n" into the Output Debug
panel. directly to the line containing the db(q).

Those are major wins. Tracing with db() is very low cost for very high
feedback.

I guess I'm not getting what that does for me. Can you explain how I would
gain from the use of such a macro? I don't use microsoft products very
often, so I really have no idea of what you are talking about. Can you
explain how I could use this macro without using a specific IDE?

Quote:
C++ has flaws. But those of you inclined to dismiss it entirely are
invited to write db(), with all these features, in your favorite language.

Who has dismissed C++?

--
"[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I think
the time has come to be serious about macro-free C++ programming." - B. S.


Back to top
E. Robert Tisdale
Guest





PostPosted: Sun Aug 29, 2004 7:42 am    Post subject: Re: To bean or not to bean Reply with quote

Steven T. Hatton wrote:

Quote:
E. Robert Tisdale wrote:

Steven T. Hatton wrote:


Stroustrup's view on classes, for the most part,
seems to be centered around the notion of invariants.
After a bit of adjusting to the use of yamt
(yet another math term) in computer science,
I came to appreciate some of the significance in what he is asserting.

Please site passage an verse.

Regarding what? I'm not sure what you are questioning.

I'm questioning your interpretation of "Stroustrup's view on classes".
I'm assuming that you read something that Stroustup wrote and published
and that you aren't communicating with him privately
and that you are not reading his mind.
It would help if you could cite publication and, perhaps,
quote the passage that he wrote.

Quote:
You probably misunderstood what Stroustrup was saying.
There is nothing terribly profound in language design.
It is a mistake to read too much into what Stroustup says.
He really tries to explain his ideas in the most straight-forward manner
using *plain* English.


I believe a good example would be the Riemann-Christoffel curvature
tensor.

No, it isn't a good example.
Very few computer programmers have cause to truck with such things.

For my purposes, it was a good example.
It is irrelevant whether a person understand
the full definition of the tensor.
Only that it has invariants,
and that it has multiple data elements, some of which are redundant.

A C++ class (or struct) is used
to introduce a User Defined Type (UDT) into a program.
A C++ class is most useful in implementing an Abstract Data Type (ADT).
The reason for data hiding (private data members) is practical.
It allows the class library developer to change the data representation
without any changes to application programs which use the class library
except, possibly, recompiling the application program and linking in
the revised class library.

I'm not sure how that really address my question.
I am asking whether the creation of a class that consists of data members
which are all manipulatable through the use of access functions
is contrary to philosophy that
a class should have a clearly defined invariant that is preserved
when operated on by invoking its member or friend functions functions.

More specifically, I am asking if the creation of a class
that consists of nothing but data fields and set and get methods
is an indication that I am doing something wrong.

It is an *indication* that you might be doing something wrong.
If only get and set methods are defined,
the object is nothing more than a "junk box".
An array (of any type) is an example of such an object.
A vector, matrix or tensor object is superficially similar to an array
but with vector arithmetic operations and other interesting methods.

I'll offer a more simple example:

class SocialSecurityNumber {
private:
unsigned long int Number;
public:
explicit
SocialSecurityNumber(unsigned long int n): Number(n) {
// throw exception if n does not represent a valid SSN
}
explicit
SocialSecurityNumber(std::string n) {
// throw an exception if n does not represent a valid SSN
}
operator unsigned long int(void) const {
return Number;
}
operator std::string(void) const {
std::ostringstream oss;
oss << Number/1000000 << '-'
<< (Number/10000)%100 << '-'
<< Number%10000;
return oss.str();
}
};

You can't do much with a social security number except set and get it.
In this case, the setter is a constructor and the getter is a type cast.
There is no "invarient" because a social security number can't change
except via the assignment operator

SocialSecurityNumber& operator=(const SocialSecurityNumber&);

All this shows is that even if all you have is getters and setters,
the needn't be named

SocialSecurityNumber::get(/* arguments */) const;
SocialSecurityNumber::set(/* arguments */);



Back to top
Steven T. Hatton
Guest





PostPosted: Sun Aug 29, 2004 9:27 am    Post subject: Re: To bean or not to bean Reply with quote

E. Robert Tisdale wrote:

Quote:
Steven T. Hatton wrote:

I'm questioning your interpretation of "Stroustrup's view on classes".
I'm assuming that you read something that Stroustup wrote and published
and that you aren't communicating with him privately
and that you are not reading his mind.
It would help if you could cite publication and, perhaps,
quote the passage that he wrote.

TC++PL(SE) 24.3.7.1 Invariants

"The values of the members and the objects referred to by members are
collectively called the /state/ of the object (or simply, its /value/). A
major concern of a class design is to get an object into a well-defined
state (initialization/construction), to maintain a well-defined state as
operations are performed, and finally to destroy the object gracefully.
The property that makes the state of an object well-defined is called
its /invariant/."
....
"Much of the skill in class design involves making a class simple enough to
make it possible to implement it so that it has a useful invariant that can
be expressed simply. It is easy enough to state that every class needs an
invariant. The hard part is to come up with a useful invariant that is
easy to comprehend and that doesn't impose unacceptable constraints on the
implementer or on the efficiency of the operations."

Quote:

I'll offer a more simple example:

class SocialSecurityNumber {
private:
unsigned long int Number;
public:
explicit
SocialSecurityNumber(unsigned long int n): Number(n) {
// throw exception if n does not represent a valid SSN
}
explicit
SocialSecurityNumber(std::string n) {
// throw an exception if n does not represent a valid SSN
}
operator unsigned long int(void) const {
return Number;
}
operator std::string(void) const {
std::ostringstream oss;
oss << Number/1000000 << '-'
(Number/10000)%100 << '-'
Number%10000;
return oss.str();
}
};

You can't do much with a social security number except set and get it.
In this case, the setter is a constructor and the getter is a type cast.
There is no "invarient" because a social security number can't change
except via the assignment operator

SocialSecurityNumber& operator=(const SocialSecurityNumber&);

All this shows is that even if all you have is getters and setters,
the needn't be named

SocialSecurityNumber::get(/* arguments */) const;
SocialSecurityNumber::set(/* arguments */);

There is an invariant in the SocialSecurityNumber. It is established by
checking that it is valid when constructed, and maintained by checking that
it is valid when assigned to.
--
"[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I think
the time has come to be serious about macro-free C++ programming." - B. S.


Back to top
Bob Hairgrove
Guest





PostPosted: Sun Aug 29, 2004 10:15 am    Post subject: Re: To bean or not to bean Reply with quote

On Sat, 28 Aug 2004 21:18:57 -0400, "Steven T. Hatton"
<susudata (AT) setidava (DOT) kushan.aa> wrote:

[snip]
Quote:
As for trailing underscores, what is your alternative?

I like to prefix the names of member data with "m_". It's only one
more character to type, and so much easier to read.

Quote:
I find it much easier
to avoid superfluous comma errors like this because I don't have to
read to the end of the line to find it.

Agreed. What about situations such as:

bigLongLeftHandSide
= bigLongIdentifier
->bigLongMemberName
->yourGonnaWrapSucker
->bigLongFunctionName();
?

I like the 80 column rule. It helps to use indentation to add
structure, as in the example above:

bigLongLeftHandSide =
bigLongIdentifier
->bigLongMemberName
->yourGonnaWrapSucker
->bigLongFunctionName();

I like to move the lines after the first one far enough over to the
right to make it obvious that they are on the RHS. And I try to avoid
overly long names, too.

My compiler usually catches missing semicolons, but often has problems
reporting a missing comma ... i.e., there will be an error message,
but it will be somewhat cryptic.

--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]

Back to top
Steven T. Hatton
Guest





PostPosted: Sun Aug 29, 2004 12:07 pm    Post subject: Re: To bean or not to bean Reply with quote

Bob Hairgrove wrote:

Quote:
On Sat, 28 Aug 2004 21:18:57 -0400, "Steven T. Hatton"
[email]susudata (AT) setidava (DOT) kushan.aa[/email]> wrote:

[snip]
As for trailing underscores, what is your alternative?

I like to prefix the names of member data with "m_". It's only one
more character to type, and so much easier to read.

I refuse! I will not be assimilated! I will never do that! Wink Actually,
after bashing my knuckles a few times on the alternative, that approach
does have its appeal. I just find it redundant. That's what /this/ is
for. And I do use /this/ religiously. The one place where it doesn't
serve me well is in the member initialization list.

I seem to recall reading that /this/ should be available there, but it has
never worked there for me when I tried to use it. I should try to look it
up in the Standard to see what is actually specified, but not right now.

Quote:
bigLongLeftHandSide =
bigLongIdentifier
->bigLongMemberName
->yourGonnaWrapSucker
->bigLongFunctionName();

I like to move the lines after the first one far enough over to the
right to make it obvious that they are on the RHS. And I try to avoid
overly long names, too.

I am slowly adjusting to using shorter names in C++. The Java dogma is to
spell out everything, and follow strict rules of capitalization. The
advantage is that it is very predictable - so long as no one decides color
should have a 'u' in it. The disadvantage is that it tends to obscure the
logic a bit, and leads to the problem we are discussing.

The place where I encounter the need to wrap my member access strings is
when working with XML DOM.

As for indenting the second and subsequent '->' or '.', my editors don't do
that by default, and I find the meaning pretty clear without the additional
indentation.

Quote:
My compiler usually catches missing semicolons, but often has problems
reporting a missing comma ... i.e., there will be an error message,
but it will be somewhat cryptic.

I prefer the editor to catch such mistakes. It took me some time to get
used to Emacs, but once I caught on, I found the syntax sensitive
indentation invaluable. Regardless of whether I'm writing DocBook EBNF XML
or C++, if I mess up the syntax, the indentation stops working after the
point where I made the mistake. KDevelop also supports a very similar kind
of behavior.

With JBuilder, the editor actually highlights syntax errors, and even
catches what I consider to be semantic errors such as using an identifier
which is not in scope. KDevelop does some of this, but I don't believe it
is even possible with C++ to provide the level of edit-time error detection
I've seen done with Java. See my signature for the reason.
--
"[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I think
the time has come to be serious about macro-free C++ programming." - B. S.


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Goto page 1, 2, 3, 4, 5  Next
Page 1 of 5

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.