Re: Pointers and polymorphism explained [preview, PDF, part of myattempted "Correct C++ Tutorial"]

Discussion in 'C++' started by James Dennett, Oct 29, 2005.

  1. Alf P. Steinbach wrote:
    > So, I got the itch to write something more...
    >
    > I apologize for not doing more on the attempted "Correct C++ Tutorial"
    > earlier, but there were reasons.
    >
    > This is an UNFINISHED and RAW document, and at the end there is even pure
    > mindstorming text left in, but already I think it can be very useful.
    >
    > <url: http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01__alpha.doc.pdf>.
    >
    >
    > What do you think?
    >
    > In particular, if you find any grave errors, please do not hesitate to
    > comment. I always make errors. Those I agree are errors will be corrected.


    It looks good, I'm pleased to say.

    I'd take issue with
    "Oddly enough C++ allows you to implement a pure virtual member
    function in the same class it’s declared as pure virtual in, and
    the effect is then only to make the class abstract."
    as the effect of marking a member function as pure virtual is to
    make abstract both the class in which it is so marked and any
    descendent class until that member function is overridden by one
    that is *not* pure.

    To illustrate: attempting to compile the code

    struct a {
    virtual void f() = 0;
    };
    void a::f() {}

    struct b:a {
    };

    int main() {
    b the_b;
    }

    will generate an error message at the attempted declaration of
    the_b in main, as b is an abstract class. Here's the output
    from two compilers (of the two, como is of course the more
    trustworthy when it comes to standards compliance):

    bash-2.05a$ make alf
    g++ -Wall -g alf.cpp -o alf
    alf.cpp: In function `int main()':
    alf.cpp:14: error: cannot declare variable `the_b' to be of type `b'
    alf.cpp:14: error: because the following virtual functions are abstract:
    alf.cpp:6: error: virtual void a::f()
    make: *** [alf] Error 1
    bash-2.05a$ como alf.cpp
    Comeau C/C++ 4.3.3 (Feb 3 2005 16:38:26) for MAC_OS_X_Alpha1
    Copyright 1988-2005 Comeau Computing. All rights reserved.
    MODE:strict errors C++

    "alf.cpp", line 14: error: object of abstract class type "b" is not allowed:
    pure virtual function "a::f" has no overrider
    b the_b;
    ^

    1 error detected in the compilation of "alf.cpp".

    I've only spotted one typo, which is in the footnote "In C++ one
    can also omit the * in a declaration of a formal function argument
    that is a function pointer, because C++ supports supports function
    types, and an argument of function type is adjusted to function
    pointer type", where the word "supports" is duplicated.

    This work in progress shows much promise. With thought I might be
    able to suggest improvements on the notes on static_cast for
    downcasting (I'm not sure of the best way to raise the fact that
    dynamic_cast is sometimes required), and I'll get around to reading
    the end of this.

    -- James
    James Dennett, Oct 29, 2005
    #1
    1. Advertising

  2. Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    * James Dennett:
    > * Alf P. Steinbach:
    > >
    > > So, I got the itch to write something more...
    > >
    > > I apologize for not doing more on the attempted "Correct C++ Tutorial"
    > > earlier, but there were reasons.
    > >
    > > This is an UNFINISHED and RAW document, and at the end there is even pure
    > > mindstorming text left in, but already I think it can be very useful.
    > >
    > > <url: http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01__alpha.doc.pdf>.
    > >
    > >
    > > What do you think?
    > >
    > > In particular, if you find any grave errors, please do not hesitate to
    > > comment. I always make errors. Those I agree are errors will be corrected.

    >
    > It looks good, I'm pleased to say.
    >
    > I'd take issue with
    > "Oddly enough C++ allows you to implement a pure virtual member
    > function in the same class it’s declared as pure virtual in, and
    > the effect is then only to make the class abstract."
    > as the effect of marking a member function as pure virtual is to
    > make abstract both the class in which it is so marked and any
    > descendent class until that member function is overridden by one
    > that is *not* pure.


    Thanks.

    I thought that was already discussed earlier in section 1.2.7, but
    checking the text I find that it was only implicit, "A class that has no
    abstract methods, i.e. it implements all abstract methods from its base
    class, if any, and doesn’t introduce any new ones itself, is
    correspondingly called a concrete class." -- not explicitly stated!

    Will fix. I'll probably use your words more or less unchanged! ;-)


    > I've only spotted one typo, which is in the footnote "In C++ one
    > can also omit the * in a declaration of a formal function argument
    > that is a function pointer, because C++ supports supports function
    > types, and an argument of function type is adjusted to function
    > pointer type", where the word "supports" is duplicated.


    Thanks again, will fix.


    > This work in progress shows much promise. With thought I might be
    > able to suggest improvements on the notes on static_cast for
    > downcasting (I'm not sure of the best way to raise the fact that
    > dynamic_cast is sometimes required)


    Well, this is (intended as) a kind of "problem - solution" driven
    exposition, and nothing that requires RTTI (dynamic_cast or typeid) has
    surfaced yet. Possibly RTTI deserves its own subsection, not to mention
    section, or chapter. E.g., students who go on to write shoot-em-up
    games often get stranded because they don't know how to design the
    system so that the X and Y-dependent effect of "X shoots at Y" can be
    naturally expressed without having to use large switch statements (if
    you're such a student reading this, one (limited) solution is to use the
    visitor pattern, which centralizes the few necessary dynamic_cast's).


    > and I'll get around to reading the end of this.


    :)

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 29, 2005
    #2
    1. Advertising

  3. James Dennett

    Robert Macy Guest

    Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    ARRRRGGGG!!!!!

    Speaking from the standpoint of a complete newbie, translate that term
    to idiot, I have no idea the point you're making in the polymorphism
    section describing linked data structures. The first example program
    starts on page 17 [page 19 of pdf] which is a program to find 2x+5.
    The length of the program and the excesses gone to in the following
    four programs to do this simple task, well, brings to mind a rude term.
    I know you're trying to teach a principle here, but I think I missed
    the principle.

    Ok, the first program has weaknesses, but compiles, and runs. The
    second program fixes some weakness, compiles, and runs. Each time the
    new version of the program fixes a weakness in the previous program. I
    very much like that, good learning structure, albeit I don't see the
    weakness, but then again I didn't even understand the program.

    However, we get to the third program starting on page 25 [page 27 of
    pdf]. It is missing critical sections relating to identity and product
    so it won't compile. Ok, ok. Something I should be able to do. After
    studying the structures of the first two programs, it should be
    possible to add the proper code to make expr_like_c_3.cpp compile. But
    alas after 5 hours I still don't have the pieces. Maybe one piece I
    could handle, but I'm not doing well on both, because I don't know what
    the pieces are supposed to do. So it's time to whine.

    Well, at least you didn't say, "It's obvious to the casual observer."
    or "I leave it to the student to fill in these pieces." :)

    Give it a few more days and maybe it'll dawn on me what goes there.

    - Robert -

    PS: It would be a nice feature to have a copy of all your source code
    zipped for download. The pdf to text converter I'm using likes to
    munge the code by removing redundant characters. No end of havoc when
    it does that to // comment lines, or randomly to function names like
    Expression becoming Expresion.
    Robert Macy, Oct 29, 2005
    #3
  4. Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    * Robert Macy:
    > ARRRRGGGG!!!!!
    >
    > Speaking from the standpoint of a complete newbie, translate that term
    > to idiot,


    Uh oh. There's a big difference between not _knowing_ and being stupid.
    I assume the reader is one how doesn't already know, but is rather
    intelligent, like you. ;-)


    > I have no idea the point you're making in the polymorphism
    > section describing linked data structures. The first example program
    > starts on page 17 [page 19 of pdf] which is a program to find 2x+5.


    Thanks, this is a good point. I tried to be clear that it's _not_ a
    program to find (or evaluate) 2x+5, but clearly that point wasn't
    expressed clearly enough... Here's a program to just evaluate 2x+5:

    #include <iostream>
    #include <ostream>

    int main()
    {
    for( int x = 0; x <= 4; ++x )
    {
    std::cout << x << ": " << 2*x+5 << std::endl;
    }
    }

    One could put 2*x+5 in a separate function (and _that_'s an exercise for
    the student), but still that would just be a program to evaluate 2x+5.

    A structured data representation of an expression, in contrast, can be

    * displayed, in various ways

    * stored in a file (this is called serialization),

    * retrieved from a file (this is called de-serialization),

    * symbolically integrated (yielding x^2 + 5x + C),

    * symbolically differentiated (yielding 2),

    * simplified (e.g. x+x+x can be simplified to 3*x)

    * dynamically combined with other expressions,

    and so on and on, all in addition to simple evaluation -- the point of
    the code is its _potential_, not the concrete expression used, or even
    what it actually does with that concrete expression, which is just to
    evaluate it to show that the representation is good enough for that.

    Now to add this clarification to the text...


    > The length of the program and the excesses gone to in the following
    > four programs to do this simple task, well, brings to mind a rude term.
    > I know you're trying to teach a principle here, but I think I missed
    > the principle.
    >
    > Ok, the first program has weaknesses, but compiles, and runs. The
    > second program fixes some weakness, compiles, and runs. Each time the
    > new version of the program fixes a weakness in the previous program. I
    > very much like that, good learning structure, albeit I don't see the
    > weakness, but then again I didn't even understand the program.
    >
    > However, we get to the third program starting on page 25 [page 27 of
    > pdf]. It is missing critical sections relating to identity and product
    > so it won't compile. Ok, ok. Something I should be able to do. After
    > studying the structures of the first two programs, it should be
    > possible to add the proper code to make expr_like_c_3.cpp compile. But
    > alas after 5 hours I still don't have the pieces. Maybe one piece I
    > could handle, but I'm not doing well on both, because I don't know what
    > the pieces are supposed to do. So it's time to whine.


    For 'identity', copy the code for 'constant', rename things, and just
    fix identity_valueOf so that it returns its x argument.

    For 'product', copy the code for 'sum', rename things, and just replace
    '+' with '*'... ;-)


    > Well, at least you didn't say, "It's obvious to the casual observer."
    > or "I leave it to the student to fill in these pieces." :)
    >
    > Give it a few more days and maybe it'll dawn on me what goes there.
    >
    > - Robert -
    >
    > PS: It would be a nice feature to have a copy of all your source code
    > zipped for download. The pdf to text converter I'm using likes to
    > munge the code by removing redundant characters. No end of havoc when
    > it does that to // comment lines, or randomly to function names like
    > Expression becoming Expresion.


    Thanks, I think I'll do that.

    Cheers,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 29, 2005
    #4
  5. James Dennett

    Robert Macy Guest

    Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    Alf P. Steinbach wrote:
    > Uh oh. There's a big difference between not _knowing_ and being stupid.
    > I assume the reader is one how doesn't already know, but is rather
    > intelligent, like you. ;-)


    I can listen to this all day.

    > For 'identity', copy the code for 'constant', rename things, and just
    > fix identity_valueOf so that it returns its x argument.
    >
    > For 'product', copy the code for 'sum', rename things, and just replace
    > '+' with '*'... ;-)


    As a double check. Is this "correct"?

    /* from page 27 - 29
    */
    #include <iostream> // std::cout
    #include <ostream> // <<, std::endl

    //------------------------------ General expression:

    struct Expression; // Explains that Expression is a struct...
    typedef Expression const* ExpressionPtr; // ... so that this is
    accepted..
    typedef double (*ValueOfFunc)( ExpressionPtr e, double x ); // ... and
    this.

    struct Expression
    {
    ValueOfFunc valueOf;
    double value; // For constant.
    ExpressionPtr pLeft; // For sum and product.
    ExpressionPtr pRight; // For sum and product.
    };

    ExpressionPtr newExpression(
    ValueOfFunc aValueOfFunc,
    double aNumber,
    ExpressionPtr aLeftPointer,
    ExpressionPtr aRightPointer
    )
    {
    Expression* pResult = new Expression;

    pResult->valueOf = aValueOfFunc;
    pResult->value = aNumber;
    pResult->pLeft = aLeftPointer;
    pResult->pRight = aRightPointer;
    return pResult;
    }

    void destroy( ExpressionPtr e )
    {
    if( e != 0 )
    {
    destroy( e->pLeft );
    destroy( e->pRight );
    }
    delete e;
    }

    double constant_valueOf( ExpressionPtr self, double /*x*/ )
    { return self->value; }

    ExpressionPtr constant( double value )
    { return newExpression( &constant_valueOf, value, 0, 0 ); }


    double identity_valueOf( ExpressionPtr self, double x )
    { return x; }

    ExpressionPtr identity()
    { return newExpression( &identity_valueOf, 0, 0, 0 ); }


    double product_valueOf( ExpressionPtr self, double x)
    {
    ExpressionPtr const left = self->pLeft;
    ExpressionPtr const right = self->pRight;
    return left->valueOf( left, x ) * right->valueOf( right, x );
    }

    ExpressionPtr product( ExpressionPtr left, ExpressionPtr right )
    { return newExpression( &product_valueOf, 0, left, right ); }


    double sum_valueOf( ExpressionPtr self, double x )
    {
    ExpressionPtr const left = self->pLeft;
    ExpressionPtr const right = self->pRight;
    return left->valueOf( left, x ) + right->valueOf( right, x );
    }

    ExpressionPtr sum( ExpressionPtr left, ExpressionPtr right )
    { return newExpression( &sum_valueOf, 0, left, right ); }


    int main()
    {
    // 2x + 5
    ExpressionPtr const e = sum( product( constant( 2 ), identity() ),
    constant( 5 ) );

    for( int x = 0; x <= 4; ++x )
    {
    std::cout << x << " " << e->valueOf( e, x ) << std::endl;
    }
    destroy( e );
    }
    /* SCREEN PRINTOUT
    0 5
    1 7
    2 9
    3 11
    4 13

    */

    It compiles and creates the correct answers, but that doesn't mean the
    pieces are correct. Could just be a "stumble" answer.

    - Robert -
    Robert Macy, Oct 30, 2005
    #5
  6. Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    * Robert Macy:
    >
    > Alf P. Steinbach wrote:
    >
    > > For 'identity', copy the code for 'constant', rename things, and just
    > > fix identity_valueOf so that it returns its x argument.
    > >
    > > For 'product', copy the code for 'sum', rename things, and just replace
    > > '+' with '*'... ;-)

    >
    > As a double check. Is this "correct"?


    Looks OK.

    Now I wonder, is the _first_ of these programs now clear?

    I'd guess, if it isn't, that it's the recursive valueOf that is the
    first thing there that is difficult to understand?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 30, 2005
    #6
  7. Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    * Alf P. Steinbach:
    > * James Dennett:
    > >
    > > I'd take issue with
    > > "Oddly enough C++ allows you to implement a pure virtual member
    > > function in the same class it’s declared as pure virtual in, and
    > > the effect is then only to make the class abstract."
    > > as the effect of marking a member function as pure virtual is to
    > > make abstract both the class in which it is so marked and any
    > > descendent class until that member function is overridden by one
    > > that is *not* pure.

    >
    > Thanks.
    >
    > I thought that was already discussed earlier in section 1.2.7, but
    > checking the text I find that it was only implicit, "A class that has no
    > abstract methods, i.e. it implements all abstract methods from its base
    > class, if any, and doesn’t introduce any new ones itself, is
    > correspondingly called a concrete class." -- not explicitly stated!
    >
    > Will fix. I'll probably use your words more or less unchanged! ;-)


    On second thoughts, is the following replacement text OK, do you think?

    (I've cautioned several places that an implementation doesn't
    necessarily use a vtable, so that's not repeated here.)

    "Oddly enough C++ allows you to implement a pure virtual member function
    in the same class it's declared as pure virtual in. This implementation
    must then be provided textually outside the class definition, and the
    only way to call it is to use a non-virtual call (a call that doesn't
    use the vtable). I haven't shown how to do either, but it's not really
    something you need yet. Just note that giving a member function an
    implementation in the same class it's declared as pure virtual in,
    doesn't make it less abstract: conceptually its vtable entry is still 0,
    because that implementation can't and will never be called via the
    vtable. So the function and the class is still abstract."

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 30, 2005
    #7
  8. Alf P. Steinbach wrote:

    > * Alf P. Steinbach:
    >
    >>* James Dennett:
    >>
    >>>I'd take issue with
    >>> "Oddly enough C++ allows you to implement a pure virtual member
    >>> function in the same class it’s declared as pure virtual in, and
    >>> the effect is then only to make the class abstract."
    >>>as the effect of marking a member function as pure virtual is to
    >>>make abstract both the class in which it is so marked and any
    >>>descendent class until that member function is overridden by one
    >>>that is *not* pure.

    >>
    >>Thanks.
    >>
    >>I thought that was already discussed earlier in section 1.2.7, but
    >>checking the text I find that it was only implicit, "A class that has no
    >>abstract methods, i.e. it implements all abstract methods from its base
    >>class, if any, and doesn’t introduce any new ones itself, is
    >>correspondingly called a concrete class." -- not explicitly stated!
    >>
    >>Will fix. I'll probably use your words more or less unchanged! ;-)

    >
    >
    > On second thoughts, is the following replacement text OK, do you think?
    >
    > (I've cautioned several places that an implementation doesn't
    > necessarily use a vtable, so that's not repeated here.)
    >
    > "Oddly enough C++ allows you to implement a pure virtual member function
    > in the same class it's declared as pure virtual in. This implementation
    > must then be provided textually outside the class definition, and the
    > only way to call it is to use a non-virtual call (a call that doesn't
    > use the vtable). I haven't shown how to do either, but it's not really
    > something you need yet. Just note that giving a member function an
    > implementation in the same class it's declared as pure virtual in,
    > doesn't make it less abstract: conceptually its vtable entry is still 0,
    > because that implementation can't and will never be called via the
    > vtable. So the function and the class is still abstract."


    Assuming that the vtable notion is clear enough to people, that
    looks good enough to me. (I'd be tempted to expand that vtable
    entries are usually set to something like pure_virtual_called
    instead of literally to null pointers, but then I have a tendency
    to dump too much information on people at once, and this may well
    be something that doesn't add clarity for your target audience.)
    So long as it's clear to readers that marking a member function
    as pure means "must be overridden by any concrete derived class,
    but does not have to be implemented in this abstract class",
    then I think the fact that pure virtuals can be implemented is
    less confusing than in the more conventional presentation of pure
    as meaning "has no implementation in this class".

    -- James
    James Dennett, Oct 30, 2005
    #8
  9. Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    * Alf P. Steinbach -> Robert Macy:
    >
    > Now I wonder, is the _first_ of these programs now clear?
    >
    > I'd guess, if it isn't, that it's the recursive valueOf that is the
    > first thing there that is difficult to understand?


    I have now added some explanation of how valueOf works.

    Plus, the example programs now display the expression. Which is a bit
    more code, but gives a better idea of the general structure. I think.

    Plus, added explanation of what the examples are all about (that the
    goal is not to display values of some concrete expression).

    <url:
    http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01__alpha3.doc.pdf>.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 31, 2005
    #9
  10. Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    Alf P. Steinbach wrote:

    > <url:
    > http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01__alpha3.doc.pdf>.
    >


    Alf -

    I posted a response a few days ago (probably soon after your original
    posting), but it has not shown up yet. Quite possible that I sent it
    to your email rather than the newsgroup.

    In any case, I remember making the following comments:

    * It would be good to have some "front matter" - initial content that
    says who the intended audience is, what they are expected to know, and
    what they should (and should not) expect to learn from this document.

    * A tutorial on pointers should not assume the reader to know what
    "rvalue" means.

    * I initially made a comment requesting broader coverage on const
    correctness. Looks like you have expanded it; will review.

    best wishes,
    - Anand Hariharan
    Anand Hariharan, Oct 31, 2005
    #10
  11. Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    * Anand Hariharan:
    >
    > Alf P. Steinbach wrote:
    >
    > > <url:
    > > http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01__alpha3.doc.pdf>.
    > >

    >
    > Alf -
    >
    > I posted a response a few days ago (probably soon after your original
    > posting), but it has not shown up yet. Quite possible that I sent it
    > to your email rather than the newsgroup.
    >
    > In any case, I remember making the following comments:
    >
    > * It would be good to have some "front matter" - initial content that
    > says who the intended audience is,


    If someone reads a text about pointers in C++, that rather narrows it
    down, doesn't it?

    In short, the audience is anyone who'd start reading.

    Perhaps a short comment: "You're reading this, so you're in the intended
    audience"?

    But on second thoughts, perhaps better not...


    > what they are expected to know,


    Basic C++. But I'm not a fan of listing requirements. That's just
    shutting people out: those who don't think they have what's listed, and
    those who have far more, and think "I've got nothing to learn here".
    With the earlier installments of that tutorial it turned out that even
    world-class experts had things to learn -- it's so easy to take the
    basics for granted, but when it's examined one finds interesting things.
    I also learned some things, of course, from the feedback and discussion.


    > and
    > what they should (and should not) expect to learn from this document.


    That's the table of contents. :)


    > * A tutorial on pointers should not assume the reader to know what
    > "rvalue" means.


    I'm aware that I've used the word before defining it, somewhere.
    Perhaps a footnote referring to the later definition?


    > * I initially made a comment requesting broader coverage on const
    > correctness. Looks like you have expanded it; will review.


    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Nov 1, 2005
    #11
  12. James Dennett

    Robert Macy Guest

    Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    In defense of leaving OUT the "who" should read this and the "what" you
    should know...I read this because of the title -the subject line - I
    need to understand pointers better and later I think I'll need to
    understand polymorphism to take advantage of code already written. So
    I waded in.

    In defense of leaving OUT the "what" you should know...Does *anybody*
    really know what they know? I mean the people that feel they know the
    least about a subject usually are experts in it. Couple that lack of
    self awareness with the hit and miss, spotty learning of programming
    and it seems unlikely to find a uniform depth knowledge of programming
    in a person, well at least a quantifiable measure of uniform depth of
    knowledge of programming.

    Besides listing requirements seems a bit pompous. Anybody who starts
    reading will quickly learn they have the background, or they do not.
    Also, they will learn whether the subject matter is taking them where
    they want to go, or it is not. Any preface describing the path is
    clutter which I have trouble reading/getting passed. I rarely read any
    document containing such a preface, because I have just learned nothing
    from reading that part, so why should I think more information will
    follow? And I stop.

    Yes, the table of contents was what I used/read to determine the path
    Alf's project was going to take. In that table of contents was not just
    a description of the path, but a quick thumbnail sketch of the
    "organization" of the presentation to follow - a valuable roadmap to
    keep in mind. Having read the table of contents I gained something.
    Having read a preface that describes what I should know and will
    shortly learn is of NO value.

    Regarding definitions...For this newbie, two words meant little as far
    as their implications were concerned. vtable and rvalue Here, a
    "glossary" would have helped. Like an expanded footnote perhaps a page
    (or more) long, but detailed enough to find out what the terms mean and
    get some concept of what the implications of using them would be. A
    separate section allows the newbie to learn, and the expert to gloss
    over. Is that where the phrase glossary came from?

    For me, this project went from learning basic concepts and principles
    [useful background for all programming] and literally plowed me to a
    dead stop into such advanced considerations my head is still spinning.
    However, each day I go back to where I mired and push a little further.
    Surprisingly, going on passed my point of understanding, and then
    coming back to where I stopped understanding has helped. Which brings
    me to my favorite question/subject. "Should we let children learn at
    their own speed?" If this means don't hold them back, YES. If this
    means, let them dawdle, NO. And that brings me back to Alf's work. He
    certainly isn't letting me dawdle.

    - Robert -
    Robert Macy, Nov 1, 2005
    #12
  13. James Dennett

    Marcus Kwok Guest

    Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    Alf P. Steinbach <> wrote:
    > <url:
    > http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01__alpha3.doc.pdf>.


    Hi Alf, I made some notes for alpha3. However, most of them seem to
    only be minor grammatical things that (IMHO) I think should be reworded.

    p.1
    --"We also say that a variable, or other object, that can hold a pointer
    value, is a pointer."

    --I would use parentheses instead, as I think there are too many
    commas.

    "We also say that a variable (or other object) that can hold ..."

    --"some times"

    --Thoughout, I would use "sometimes" instead of "some times"

    --"and is essential to for example modern GUI (graphical user interface)
    programming."

    --I would add commas here

    "and is essential to, for example, modern GUI ..."

    --"Finally, due to the heritage from C the C++ language is in many
    respects strongly tied to use of pointers"

    --I would add a comma, and the word "the" should be added

    "Finally, due to the heritage from C, the C++ language is in many
    respects strongly tied to the use of pointers"

    p.3
    --"MingW"

    --I believe it's "MinGW" (with a capital 'G')

    p.6
    --"Another example is an object within a std::vector, when that vector is
    resized, e.g. when a new object added via push_back;"

    --Add comma after "e.g.", add "is" to phrase

    "... when that vector is resized, e.g., when a new object is added
    via push_back;"

    p.7
    --"NRVO"

    --You do not state what the 'N' stands for

    --"Then the client code programmer, who knows more both about the client
    code, the compiler and the acceptable efficiency"

    --Remove the word "both", as it should be used when there are only two
    things

    p.9
    --"That is, pNumbers is a pointer to a read-only IntVector. An IntVector
    that can be read from, but not modified."

    --I would change the period to a colon, since the second sentence has
    no predicate

    p.10
    --"... IntVectors laid end to end in memory, a raw array of IntVectors,
    and if so, how many?"

    --I would add hyphens to "end to end", and delimit the "a raw array
    of IntVectors" phrase with "i.e.,"

    "... IntVectors laid end-to-end in memory, i.e., a raw array of
    IntVectors, ..."

    p.14
    --"const is generally a restriction on operations, and you're not
    allowed to remove a restriction on operations without at least telling
    the compiler that you really mean it, the black book incantations I
    hinted about."

    --Add the word "of"

    "... the black book of incantations I hinted about."

    p.23
    --Code listing

    --Maybe I missed something, but the variable "e" (used in
    stringFrom(e)) has not been declared.

    --"it's a showstopper problem, let's tackle this latest problem first of
    all."

    --I would add the word "so"

    "it's a showstopper problem, so let's tackle ..."

    p.30
    --Footnote i

    --Does a static class method not count as "a type-specific function
    that doesn't need to know anything about the object it's called on,
    except the type"?

    p.34
    --Parts hierarchy

    --I've also heard this described as a "HasA-hierarchy", which would
    parallel your "IsA-hierarchy"

    --"... and (3) calling delete on a Sum object in destroy, and
    correspondingly for Product."

    --I would delimit the comment about Product with a semicolon

    "... calling delete on a Sum object in destroy; and correspondingly
    for Product."

    p.39
    --"So given a pointer to an Expression object, if you call destroy on
    that object the function implementation to execute will be the one"

    --I would add a comma

    "... if you call destroy on that object, the function ..."

    p.43
    --"or, the BinaryOperator destruction code is calling one of those
    methods - for an implementation that more formally correct moves the
    object's vtable pointer up again in the class hierarchy on
    destruction, which hasn't been an issue in this implementation."

    --I did not understand the phrase that starts with "for an
    implementation..."

    --"Any way it would indicate a serious bug"

    --I would make "Any way" one word, and add a comma

    "Anyway, it would indicate ..."

    p.45
    --"But in this subsection I focus only on what C++ can do for our
    vtables and function pointers and function naming and downcasts and
    call syntax, in short, for our method support"

    --I would change a comma to a semicolon

    "... and call syntax; in short, for our method support"

    p.48
    --Yellow box

    --I think it would be clearer if you used commas/semicolons in
    different places. I would either remove the comma before "uses a
    vtable", or I would change the comma after that phrase to a
    semicolon

    either:
    "A class that has at least one virtual member function uses a
    vtable, and every object of that class has a vtable pointer."

    or:
    "A class that has at least one virtual member function, uses a
    vtable; and every object of that class has a vtable pointer."

    p.49
    --"a C++ base class implementation of a virtual member function foo, and
    its override in a derived class D, have the same name, namely just
    foo, no name prefixes like we had to use when coding in C-style."

    --I would change a comma to a semicolon

    "... namely just foo; no name prefixes ..."

    p.62
    --"Resource Release is Destruction"

    --I would call it "Destruction is Resource Release" (though I also
    have never seen either RRID nor DIRR, so you can call it whatever
    you like)

    p.63
    --"It also, first, allocates memory for the object from the heap, which
    until now we've thought was primary."

    --I did not understand the comment about "[thinking it] was primary"

    p.64
    --"The constructor call guarantee is not an absolute guarantee, and it's
    not stated or referred to anywhere in the standard, but it's what the
    detailed rules are designed to provide, it holds unless you use very
    low-level language features"

    --Change to semicolon

    "it's what the detailed rules are designed to provide; it holds
    unless ..."


    Great work, Alf!

    --
    Marcus Kwok
    Marcus Kwok, Nov 15, 2005
    #13
  14. James Dennett

    Marcus Kwok Guest

    Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    Sorry to follow up to myself.

    Marcus Kwok <> wrote:
    > Hi Alf, I made some notes for alpha3. However, most of them seem to
    > only be minor grammatical things that (IMHO) I think should be reworded.
    >
    > p.48
    > --Yellow box
    >
    > --I think it would be clearer if you used commas/semicolons in
    > different places. I would either remove the comma before "uses a
    > vtable", or I would change the comma after that phrase to a
    > semicolon
    >
    > either:
    > "A class that has at least one virtual member function uses a
    > vtable, and every object of that class has a vtable pointer."
    >
    > or:
    > "A class that has at least one virtual member function, uses a
    > vtable; and every object of that class has a vtable pointer."


    On further review, I think the first alternative is the clearest.

    > p.62
    > --"Resource Release is Destruction"
    >
    > --I would call it "Destruction is Resource Release" (though I also
    > have never seen either RRID nor DIRR, so you can call it whatever
    > you like)


    Actually, I just found a few:
    http://www.google.com/search?q="resource release is destruction"

    Far fewer results:
    http://www.google.com/search?q="destruction is resource release"

    --
    Marcus Kwok
    Marcus Kwok, Nov 15, 2005
    #14
  15. Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    * Marcus Kwok:
    > Alf P. Steinbach <> wrote:
    > > <url:
    > > http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01__alpha3.doc.pdf>.

    >
    > Hi Alf, I made some notes for alpha3. However, most of them seem to
    > only be minor grammatical things that (IMHO) I think should be reworded.


    Thanks. I've followed your recommendations to the letter (!), with two
    exceptions; noted below.


    [snip]
    > p.7
    > --"NRVO"
    >
    > --You do not state what the 'N' stands for


    Named Return Value Optimization. Originally some compilers, such as (if
    memory serves me right) g++ 2.95, offered a special syntax for naming
    the return value of a function, and that was then called NRVO. Nowadays
    NRVO instead stands for the case of

    SomeType foo()
    {
    SomeType whatever;
    ...
    return whatever;
    }

    where the 'return' value is a local variable. This special opportunity
    for optimization (e.g. the compiler can arrange for a pointer to local
    storage at the calling site to be passed to foo() so that the return
    statement can copy construct the SomeType object directly into local
    storage at the calling site, instead of going via a temporary) is
    especially mentioned somewhere in the standard.


    [snip]
    > --"const is generally a restriction on operations, and you're not
    > allowed to remove a restriction on operations without at least telling
    > the compiler that you really mean it, the black book incantations I
    > hinted about."
    >
    > --Add the word "of"
    >
    > "... the black book of incantations I hinted about."


    I meant the incantations, not the book. How to rephrase, if that's
    still Bad English?


    > p.23
    > --Code listing
    >
    > --Maybe I missed something, but the variable "e" (used in
    > stringFrom(e)) has not been declared.


    Yep, sorry.

    It should be 'e2xplus5'.



    > --"it's a showstopper problem, let's tackle this latest problem first of
    > all."
    >
    > --I would add the word "so"
    >
    > "it's a showstopper problem, so let's tackle ..."


    There is a 'because' earlier in that long paragraph, so 'so' would be
    misplaced, I think. "because of [this and that], which is a showstopper
    problem, let's tackle...".



    > p.30
    > --Footnote i
    >
    > --Does a static class method not count as "a type-specific function
    > that doesn't need to know anything about the object it's called on,
    > except the type"?


    Yes, it does, but what I unsuccessfully tried to convey was the notion
    of a virtual member function that doesn't need a 'this' pointer, i.e. a
    member function where the actual implementation executed for a call on
    an object o depends on the dynamic type of o; which is not the case for
    a static member function.

    Discussing that before virtual member functions have been introduced.

    Which is difficult, especially in a footnote with limited space...

    Suggestions?



    [snip]
    > p.43
    > --"or, the BinaryOperator destruction code is calling one of those
    > methods - for an implementation that more formally correct moves the
    > object's vtable pointer up again in the class hierarchy on
    > destruction, which hasn't been an issue in this implementation."
    >
    > --I did not understand the phrase that starts with "for an
    > implementation..."


    If you study the C-style implementation in that subsection, you'll see
    that initialization effectively first sets the object's vtable pointer
    to point to Expression's vtable, then to (say) BinaryOperator's vtable,
    and finally to (say) Product's vtable, for initialization of a Product
    object. That's just what the C++ OO support also does, to ensure that
    one does not call a function in a derived class before initialization at
    the derived class level has at least started; otherwise the derived
    class function could be called and access uninitialized things, and
    that's a not uncommon problem in e.g. Java and I think also in C#.
    Destruction is opposite, and the C++ OO support then moves the vtable
    pointer successively up in the inheritance chain, again to prevent
    mishaps where a function otherwise could access uninitialized things.

    Assuming (1) a vtable based C++ implementation and (2) that each class
    at most inherits from one class.

    Should I mention this, do you think? The document just gets longer and
    longer...


    [snip]
    >
    > Great work, Alf!


    Thanks, for very detailed corrections! I'll post a beta version Really
    Really Soon Now.

    The things added are roughly

    1.3 Dynamically allocated objects versus others.
    1.3.1 Ensure dynamic allocation by using C++ access specifiers &
    friendship.
    1.3.2 An aside on wrapping boost::shared_ptr (a.k.a.
    std::tr1::shared_ptr).
    1.3.3 Ensure that smart pointers are used, by overloading operator
    new.
    1.3.4 Combat slicing by removing access to copy assignment.
    1.3.5 Value copying problems & possible solutions.
    1.3.6 Cloning as a solution to ownership and aliasing problems.
    1.3.7 Intentional sharing as a solution to ownership and aliasing
    problems.
    1.4 Basic serialization and de-serialization.
    1.4.1 Functions that possibly don't succeed: introducing exception
    handling.
    1.4.2 Exception usage example: conversion between numeric values
    and text.
    1.4.3 A serialization format for hierarchical data structures.
    1.4.4 De-serialization: the parser.
    1.4.5 Serialization: the generator [currently unfinished].
    1.5 Notes on C++ inheritance.
    1.6 Summary [a little more to do].
    1.7 Acknowledgements.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Nov 15, 2005
    #15
  16. James Dennett

    Marcus Kwok Guest

    Re: Pointers and polymorphism explained [preview, PDF, part of my attempted "Correct C++ Tutorial"]

    Alf P. Steinbach <> wrote:
    > * Marcus Kwok:
    >> Hi Alf, I made some notes for alpha3. However, most of them seem to
    >> only be minor grammatical things that (IMHO) I think should be reworded.

    >
    > Thanks. I've followed your recommendations to the letter (!), with two
    > exceptions; noted below.
    >
    > [snip]
    >> --"const is generally a restriction on operations, and you're not
    >> allowed to remove a restriction on operations without at least telling
    >> the compiler that you really mean it, the black book incantations I
    >> hinted about."
    >>
    >> --Add the word "of"
    >>
    >> "... the black book of incantations I hinted about."

    >
    > I meant the incantations, not the book. How to rephrase, if that's
    > still Bad English?


    How about, "telling the compiler that you really mean it, by using one
    of the black book incantations ..."?

    >> --"it's a showstopper problem, let's tackle this latest problem first of
    >> all."
    >>
    >> --I would add the word "so"
    >>
    >> "it's a showstopper problem, so let's tackle ..."

    >
    > There is a 'because' earlier in that long paragraph, so 'so' would be
    > misplaced, I think. "because of [this and that], which is a showstopper
    > problem, let's tackle...".


    Hmm, the way I read it was like, "because of [this and that], it is a
    showstopper problem, so let's tackle...", making the "so" sound better
    to me. IMO I think it's clearer this way anyway. Or you could reword
    it like, "because [this stuff] is not just extremely inconvenient, but
    is a showstopper because it prevents us from [doing other stuff], let's
    tackle..." (though I prefer the first way).

    >> p.30
    >> --Footnote i
    >>
    >> --Does a static class method not count as "a type-specific function
    >> that doesn't need to know anything about the object it's called on,
    >> except the type"?

    >
    > Yes, it does, but what I unsuccessfully tried to convey was the notion
    > of a virtual member function that doesn't need a 'this' pointer, i.e. a
    > member function where the actual implementation executed for a call on
    > an object o depends on the dynamic type of o; which is not the case for
    > a static member function.
    >
    > Discussing that before virtual member functions have been introduced.
    >
    > Which is difficult, especially in a footnote with limited space...
    >
    > Suggestions?


    Hmm, I guess what we're looking for is something like the notion of a
    "static virtual member function"[0], which is not allowed. But since
    you haven't introduced virtual member functions yet, I'm not sure of a
    good way to explain this. Maybe you could mention this idea in the
    footnote, but tell the reader to come back to it after you explain
    virtual functions.

    >> p.43
    >> --"or, the BinaryOperator destruction code is calling one of those
    >> methods - for an implementation that more formally correct moves the
    >> object's vtable pointer up again in the class hierarchy on
    >> destruction, which hasn't been an issue in this implementation."
    >>
    >> --I did not understand the phrase that starts with "for an
    >> implementation..."

    >
    > If you study the C-style implementation in that subsection, you'll see
    > that initialization effectively first sets the object's vtable pointer
    > to point to Expression's vtable, then to (say) BinaryOperator's vtable,
    > and finally to (say) Product's vtable, for initialization of a Product
    > object. That's just what the C++ OO support also does, to ensure that
    > one does not call a function in a derived class before initialization at
    > the derived class level has at least started; otherwise the derived
    > class function could be called and access uninitialized things, and
    > that's a not uncommon problem in e.g. Java and I think also in C#.
    > Destruction is opposite, and the C++ OO support then moves the vtable
    > pointer successively up in the inheritance chain, again to prevent
    > mishaps where a function otherwise could access uninitialized things.
    >
    > Assuming (1) a vtable based C++ implementation and (2) that each class
    > at most inherits from one class.
    >
    > Should I mention this, do you think? The document just gets longer and
    > longer...


    OK, I see now. In light of this, how about:

    "or, the BinaryOperator destruction code is calling one of those
    methods, which could occur on a (more formally correct) implementation
    that moves the object's vtable pointer up again in the class hierarchy
    on destruction (which hasn't been an issue in this implementation)."

    >> Great work, Alf!

    >
    > Thanks, for very detailed corrections! I'll post a beta version Really
    > Really Soon Now.


    Great, I look forward to it.

    [0]
    What I mean by a "static virtual member function":

    // NOT ALLOWED IN C++
    class Base
    {
    public:
    static virtual void doThis() { std::cout << "Base::doThis()\n"; }
    };

    class Derived : public Base
    {
    public:
    static virtual void doThis() { std::cout << "Derived::doThis()\n"; }
    };

    int main()
    {
    Base* b = new Derived;
    b->doThis();

    return 0;
    }

    and have it resolve properly to Derived::doThis(). If I just make
    doThis() static, it calls Base::doThis(), and if I just make it virtual,
    it calls Derived::doThis() (as it should).

    --
    Marcus Kwok
    Marcus Kwok, Nov 15, 2005
    #16
    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.

Share This Page