To bean or not to bean

Discussion in 'C++' started by Steven T. Hatton, Aug 28, 2004.

  1. 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.
     
    Steven T. Hatton, Aug 28, 2004
    #1
    1. Advertising

  2. On Sat, 28 Aug 2004 04:39:31 -0400, "Steven T. Hatton"
    <> 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>

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

    [snip]
    > 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
     
    Bob Hairgrove, Aug 28, 2004
    #2
    1. Advertising

  3. "Bob Hairgrove" <> wrote...
    > [..]
    > 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
     
    Victor Bazarov, Aug 28, 2004
    #3
  4. Bob Hairgrove wrote:

    > On Sat, 28 Aug 2004 04:39:31 -0400, "Steven T. Hatton"
    > <> 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.

    >> 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.


    > 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?

    > 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.
     
    Steven T. Hatton, Aug 29, 2004
    #4
  5. Victor Bazarov wrote:

    > 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.
     
    Steven T. Hatton, Aug 29, 2004
    #5
  6. Steven T. Hatton

    Phlip Guest

    Steven T. Hatton wrote:

    > 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.)

    > 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?

    > -- "[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
     
    Phlip, Aug 29, 2004
    #6
  7. 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.
    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.

    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.
     
    E. Robert Tisdale, Aug 29, 2004
    #7
  8. Phlip wrote:

    > 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.

    > 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.
     
    Steven T. Hatton, Aug 29, 2004
    #8
  9. Steven T. Hatton

    Phlip Guest

    Steven T. Hatton wrote:

    > 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:\path\source.cpp(99) : q = 5\n" into the Output Debug panel.
    <F8> parses the file name and line number and navigates your editor directly
    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
     
    Phlip, Aug 29, 2004
    #9
  10. 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.

    > 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 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.
     
    Steven T. Hatton, Aug 29, 2004
    #10
  11. Phlip wrote:

    > 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?

    > - stringerization


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

    > - 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.

    > 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:\path\source.cpp(99) : q = 5\n" into the Output Debug
    > panel. <F8> parses the file name and line number and navigates your editor
    > 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?

    > 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.
     
    Steven T. Hatton, Aug 29, 2004
    #11
  12. Steven T. Hatton wrote:

    > 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.

    >>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::eek:stringstream 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 */);
     
    E. Robert Tisdale, Aug 29, 2004
    #12
  13. E. Robert Tisdale wrote:

    > 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."

    >
    > 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::eek:stringstream 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.
     
    Steven T. Hatton, Aug 29, 2004
    #13
  14. On Sat, 28 Aug 2004 21:18:57 -0400, "Steven T. Hatton"
    <> 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 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
     
    Bob Hairgrove, Aug 29, 2004
    #14
  15. Bob Hairgrove wrote:

    > On Sat, 28 Aug 2004 21:18:57 -0400, "Steven T. Hatton"
    > <> 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! ;) 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.

    > 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.

    > 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.
     
    Steven T. Hatton, Aug 29, 2004
    #15
  16. Steven T. Hatton

    Phlip Guest

    Steven T. Hatton wrote:

    > > Use the Cpp for:
    > >
    > > - token pasting


    > Why? What can that give me that I cannot achieve using the internal
    > features of the language?


    The TEST_() macro uses it.

    > > - stringerization

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


    My #define db() sample.

    > > - 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.


    That's my point. Those who bust on the CPP overlook CC, and CC works fine to
    make large systems managable, such as Linux.

    Another great thing about the CPP is it's language-agnostic (so long as you
    don't find a language that does not balance "" and () operators, or use
    commas for something silly). So the same macros can influence, for example,
    your .cpp, .rc, and .idl files, etc.

    > > 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:\path\source.cpp(99) : q = 5\n" into the Output Debug
    > > panel. <F8> parses the file name and line number and navigates your

    editor
    > > 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?


    It is a trace macro, like TRACE(). You put an expression in, and the macro
    inserts its value into both the console and the Output panel (which all MS
    Windows IDEs support).

    Read my verbiage again.

    > > 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++?


    I copied that repost from an essay, where, as a rhetorical technique, I
    hypothesized that someone dismissed C++.

    --
    Phlip
    http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces
     
    Phlip, Aug 29, 2004
    #16
  17. Phlip wrote:

    > Steven T. Hatton wrote:
    >
    >> > Use the Cpp for:
    >> >
    >> > - token pasting

    >
    >> Why? What can that give me that I cannot achieve using the internal
    >> features of the language?

    >
    > The TEST_() macro uses it.


    What is the TEST_() macro? I searched the ISO/IEC 14882:2003 for the string
    "TEST" using acrobat, and got no hits. I assume it is not part of standard
    C++?

    >> > - stringerization

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

    >
    > My #define db() sample.


    That doesn't explain what the word means.

    >> > - 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.

    >
    > That's my point. Those who bust on the CPP overlook CC, and CC works fine
    > to make large systems managable, such as Linux.


    Linux is written in C. It is a very controlled development process that
    requires a great deal of specialized expertise to work on. Working on any
    given component does not require knowledge of a wide variety of rapidly
    changing interfaces.

    I really don't know what you mean by the "CC". To me, CC is a somewhat
    antiquated alias for the C Compiler.

    Now if you want to talk about program suites such as the KDE, /that/ is
    written in C++ using Qt. I've been working with the KDE since spring of
    1997. It is an extremely impressive project, with many gifted
    contributors. The component of the KDE which I have spent a good deal of
    the past several months working with is KDevelop. That is the IDE
    distrubuted with the KDE. I am acutely aware of its capabilities and
    limitations.

    I've also worked with J2EE fairly extensively. For purposes of developing
    enterprise applications such as the web based interface for the US Army's
    personnel database, BEA's WebLogic is easier to use, and facilitates faster
    development than anything I know of based on C++.

    > Another great thing about the CPP is it's language-agnostic (so long as
    > you don't find a language that does not balance "" and () operators, or
    > use commas for something silly). So the same macros can influence, for
    > example, your .cpp, .rc, and .idl files, etc.


    That doesn't address the problems created by using the CPP.

    http://www.freshsources.com/bjarne/ALLISON.HTM

    //--------------excerpt-----------------------------
    CUJ: What do you do for your day job now?

    BS: I'm trying to build up a research group to focus on large-scale
    programming -- that is, to do research on the use of programming in large
    programs rather than just language design, just the study of small
    (student) programs, or the exclusive focus on design and/or process. I
    think that programming technique, programming language, and the individual
    programmer have a central role in the development of large systems. Too
    often, either the scale of industrial projects or the role of programming
    is ignored. This research will involve work on libraries and tools.
    ....

    CUJ: What is the next step in the evolution of C++?

    BS: Tools/environments and library design. I'd like to see incremental
    compilers and linkers for C++. Something like two seconds is a suitable
    time for re-compiling and re-linking a medium-sized C++ program after a
    change that is localized to a few functions. I'd like to see browsers and
    analysis tools that know not only syntax but also the type of every entity
    of a program. I'd like to see optimizers that actually take notice of C++
    constructs and do a decent job of optimizing them, rather than simply
    throwing most of the useful information away and giving the rest to an
    optimizer that basically understands only C. I'd like to see debuggers
    integrated with the incremental compiler so that the result approximates a
    C++ interpreter. (I'd also like to see a good portable C++ interpreter.)
    None of this is science fiction; in fact, I have seen experimental versions
    of most of what I suggest -- and more. We still suffer from
    first-generation C++ environments and tools.
    ....

    The preprocessor is one of the main factors that has led to the lack of more
    sophisticated C program development environments: the fact that the source
    text seen by the programmer isn't the text seen by the compiler is a
    crippling handicap. I think the time has come to be serious about
    macro-free C++ programming.
    //--------------end-excerpt-----------------------------

    > It is a trace macro, like TRACE(). You put an expression in, and the macro
    > inserts its value into both the console and the Output panel (which all MS
    > Windows IDEs support).
    >
    > Read my verbiage again.


    Either I'm missing something, or that is far from impressive. The average
    Java IDE can trace code and show me the value of any variable in detail. I
    can also browse through the activation stack which is presented as a
    clickable tree with all the classes and class members available for
    inspection.

    --
    "[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.
     
    Steven T. Hatton, Aug 29, 2004
    #17
  18. Steven T. Hatton

    Phlip Guest

    Steven T. Hatton wrote:

    > Phlip wrote:


    > >> > Use the Cpp for:
    > >> >
    > >> > - token pasting


    > > The TEST_() macro uses it.

    >
    > What is the TEST_() macro? I searched the ISO/IEC 14882:2003 for the

    string
    > "TEST" using acrobat, and got no hits. I assume it is not part of standard
    > C++?


    Steve, people are allowed to write other macros than those that appear in
    The Standard. Google this newsgroup for my street name, TEST_, and
    Steinbach.

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

    > >
    > > My #define db() sample.

    >
    > That doesn't explain what the word means.


    Look inside my macro for the # operator.

    > >> > - 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.

    > >
    > > That's my point. Those who bust on the CPP overlook CC, and CC works

    fine
    > > to make large systems managable, such as Linux.

    >
    > Linux is written in C.


    Snip from here down. I can't find evidence you are reading my posts.

    Please take a deep breath, and entertain the idea that passionately decrying
    a handful of keywords is a kind of zealotry.

    --
    Phlip
    http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces
     
    Phlip, Aug 29, 2004
    #18
  19. Cpp Considered Harmfull:was:Re: To bean or not to bean

    Phlip wrote:

    > Steven T. Hatton wrote:
    >
    >> Phlip wrote:

    >
    >> >> > Use the Cpp for:
    >> >> >
    >> >> > - token pasting

    >
    >> > The TEST_() macro uses it.

    >>
    >> What is the TEST_() macro? I searched the ISO/IEC 14882:2003 for the

    > string
    >> "TEST" using acrobat, and got no hits. I assume it is not part of
    >> standard C++?

    >
    > Steve, people are allowed to write other macros than those that appear in
    > The Standard. Google this newsgroup for my street name, TEST_, and
    > Steinbach.


    This is silly. You used a macro that you wrote as an example that I am
    expected to be familiar with, without even mentioning that you wrote it.

    >> >> > - stringerization
    >> >>
    >> >> I'm not familiar with the term. Care to explain?
    >> >
    >> > My #define db() sample.

    >>
    >> That doesn't explain what the word means.

    >
    > Look inside my macro for the # operator.


    Perhaps you could simply provide a definition for the term. My attempting
    to extract a definition from an example has the significant potential for
    my arriving at a different definition than the one you intend.

    > Snip from here down. I can't find evidence you are reading my posts.
    >
    > Please take a deep breath, and entertain the idea that passionately
    > decrying a handful of keywords is a kind of zealotry.


    Sorry if you were confused by my use of words I learned in college when I
    studied computer science. I can't say I will refrain from doing so in the
    future, but I will do my best to restrict my vocabulary when addressing you
    directly.

    Now, back to the topic at hand. I changed the subject field in the heading
    to reflect the fork this thread has taken. For the moment, forget any of
    my own comments regarding the Cpp, and explain to the news group where
    Bjarne Stroustrup is in error regarding the opinions expressed in the
    following:


    http://www.freshsources.com/bjarne/ALLISON.HTM

    //--------------excerpt-----------------------------
     CUJ: What do you do for your day job now?

    BS: I'm trying to build up a research group to focus on large-scale
    programming -- that is, to do research on the use of programming in large
    programs rather than just language design, just the study of small
    (student) programs, or the exclusive focus on design and/or process. I
    think that programming technique, programming language, and the individual
    programmer have a central role in the development of large systems. Too
    often, either the scale of industrial projects or the role of programming
    is ignored. This research will involve work on libraries and tools.
    ....

     CUJ: What is the next step in the evolution of C++?

    BS: Tools/environments and library design. I'd like to see incremental
    compilers and linkers for C++. Something like two seconds is a suitable
    time for re-compiling and re-linking a medium-sized C++ program after a
    change that is localized to a few functions. I'd like to see browsers and
    analysis tools that know not only syntax but also the type of every entity
    of a program. I'd like to see optimizers that actually take notice of C++
    constructs and do a decent job of optimizing them, rather than simply
    throwing most of the useful information away and giving the rest to an
    optimizer that basically understands only C. I'd like to see debuggers
    integrated with the incremental compiler so that the result approximates a
    C++ interpreter. (I'd also like to see a good portable C++ interpreter.)
    None of this is science fiction; in fact, I have seen experimental versions
    of most of what I suggest -- and more. We still suffer from
    first-generation C++ environments and tools.
    ....

    The preprocessor is one of the main factors that has led to the lack of more
    sophisticated C program development environments: the fact that the source
    text seen by the programmer isn't the text seen by the compiler is a
    crippling handicap. I think the time has come to be serious about
    macro-free C++ programming.
    //--------------end-excerpt-----------------------------

    --
    "[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.
     
    Steven T. Hatton, Aug 29, 2004
    #19
  20. Steven T. Hatton wrote:

    > E. Robert Tisdale wrote:
    >
    >>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."
    >
    >>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::eek:stringstream 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.


    Yes. The invariant is trivial.
    And I think that your understanding of invariance is consistent
    with the way that Stroustrup uses the term.
    Notice that, in the example above, there is no way to construct
    an invalid SocialSecurityNumber and no assignment is defined
    except the default assignment from another valid SocialSecurityNumber.
     
    E. Robert Tisdale, Aug 29, 2004
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Benjamin Stewart

    To bean or not to bean...

    Benjamin Stewart, Jun 30, 2003, in forum: Java
    Replies:
    0
    Views:
    821
    Benjamin Stewart
    Jun 30, 2003
  2. David Thielen
    Replies:
    2
    Views:
    812
    Marek Lange
    Sep 12, 2003
  3. Markku Salminen
    Replies:
    3
    Views:
    5,871
    Michael Borgwardt
    Jan 21, 2004
  4. Takeshi
    Replies:
    0
    Views:
    526
    Takeshi
    Jan 28, 2004
  5. jill
    Replies:
    5
    Views:
    15,724
Loading...

Share This Page