An kind of member function name scope specification

Discussion in 'C++' started by Stefan Ram, Apr 26, 2009.

  1. Stefan Ram

    Stefan Ram Guest

    For teaching purposes, I wrote this program as a first
    example of a definition of a class with non-static functions:

    #include <iostream>
    #include <ostream>

    class Account
    { private:
    double balance_;
    public:
    Account( double const balance );
    double balance(); };

    ::Account::Account( double const balance )
    { this->balance_ = balance; }

    double ::Account::balance()
    { return this->balance_; }

    int main()
    { Account acct( 100 );
    ::std::cout << acct.::Account::balance() << '\n';
    ::std::cout << acct.balance() << '\n'; }

    (End of program.)

    Regarding »acct.::Account::balance()«:

    I was not aware that such a full qualification of a member
    function in a member function call was possible at all.

    When would one need this? (To call an overloaded function
    of a base class?)

    Can the above definition of the class still be improved somehow?

    ~~

    Is such an account class is a good example for teaching?

    I need the first example to be very simple, yet it needs
    to suggest to be useful and related to applications of
    the language.

    Are there any other good examples of classes, that are

    - small and simple
    - not already part of the standard library
    - not requiring special knowledge of a field
    - looking somewhat natural and useful

    ?

    Account classes are used often.

    Sometimes, a class for complex numbers is used in teaching,
    but such a class already is defined in the standard library
    and might look too »mathematical«.

    The only other topic that comes to my mind right now
    would be a class for a compound date (YYYY, MM, DD)
    or time (HH, MM) object.
    Stefan Ram, Apr 26, 2009
    #1
    1. Advertising

  2. Stefan Ram

    Stefan Ram Guest

    -berlin.de (Stefan Ram) writes:
    >::Account::Account( double const balance )
    >Can the above definition of the class still be improved somehow?


    Except for using a member initialization list,
    which I intentionally omitted in this first example.
    Stefan Ram, Apr 26, 2009
    #2
    1. Advertising

  3. Stefan Ram

    Ian Collins Guest

    Stefan Ram wrote:
    > For teaching purposes, I wrote this program as a first
    > example of a definition of a class with non-static functions:
    >
    > #include <iostream>
    > #include <ostream>
    >
    > class Account
    > { private:
    > double balance_;
    > public:
    > Account( double const balance );
    > double balance(); };
    >
    > ::Account::Account( double const balance )
    > { this->balance_ = balance; }
    >
    > double ::Account::balance()
    > { return this->balance_; }
    >
    > int main()
    > { Account acct( 100 );
    > ::std::cout << acct.::Account::balance() << '\n';
    > ::std::cout << acct.balance() << '\n'; }
    >
    > (End of program.)
    >
    > Regarding »acct.::Account::balance()«:
    >
    > I was not aware that such a full qualification of a member
    > function in a member function call was possible at all.
    >
    > When would one need this? (To call an overloaded function
    > of a base class?)


    Yes, try adding

    struct Base
    {
    double balance() { return 42; }
    };

    class Account : public Base

    and

    std::cout << acct.::Base::balance() << '\n';

    > Can the above definition of the class still be improved somehow?


    You can do away with the superfluous leading :: :):std::).

    I assume the layout was to compress the code for Usenet?

    The this-> in balance() is superfluous, as is the leading ::.

    balance() should be declared cost if it doesn't change anything.

    No too big a deal here, but in general geters are a design smell.

    --
    Ian Collins
    Ian Collins, Apr 26, 2009
    #3
  4. Stefan Ram

    Stefan Ram Guest

    Ian Collins <> writes:
    >> #include <iostream>
    >> #include <ostream>
    >>
    >> class Account
    >> { private:
    >> double balance_;
    >> public:
    >> Account( double const balance );
    >> double balance(); };
    >>
    >> ::Account::Account( double const balance )
    >> { this->balance_ = balance; }
    >>
    >> double ::Account::balance()
    >> { return this->balance_; }
    >>
    >> int main()
    >> { Account acct( 100 );
    >> ::std::cout << acct.::Account::balance() << '\n';
    >> ::std::cout << acct.balance() << '\n'; }
    >>

    >I assume the layout was to compress the code for Usenet?


    The above layout contains 4 blank lines,
    separating the 5 major parts of the source:

    - include directives
    - a class specifier
    - a member function definition
    - another member function definition and
    - a function definition

    If I would add additional empty lines within
    each of these parts, those 4 top-most separators
    would not stand out in the prominent way the do now.

    So this is some kind of global scope view.

    If I would show only the class specifier, I might
    have used vertical spacing for this, maybe like:

    class Account
    {
    private:
    double balance_;

    public:
    Account( double const balance );
    double balance(); };

    So, maybe I do not consider formatting to be static, but to be
    dynamic. The format used by me in the OP was focused on the
    large-scale structure of the source code. If I would have to
    edit a function definition, I might start by »unpacking« it,
    that is, by inserting some vertical space to see more of the
    smaller-scale structure. I assume that readers will adapt the
    layout to their current need. I do not deem the layout chosen
    by me to be best for all purposes.
    Stefan Ram, Apr 26, 2009
    #4
  5. Stefan Ram

    Stefan Ram Guest

    Ian Collins <> writes:
    >>public:
    >>Account( double const balance );
    >>double balance(); };

    >No too big a deal here, but in general geters are a design smell.


    Yes, but I do not see a getter here. Let me explain why:

    I have quoted the public interface of the class above.

    It misses an important feature: documentation.

    So I will add that document now in the way the names suggest:

    - The constructor initializes a new account with
    an opening balance as the argument.

    - The function »balance« returns the current balance
    of the account.

    No mentioning of private fields in the documentation.

    So a client/caller/reader of this interface can not know
    whether this function returns the value of a private field or
    obtains the balance using some other means. He does not know
    which fields an object of this class has. Therefore, I do not
    deem »balance« to be a getter, just a non-void function.

    I would see a getter, if the documentation would read instead:

    - Each object of this class has a field named »balance_«.
    The function »balance« returns the value of this field.

    (Admittedly, my code does not have documentation, so both
    interpretations are possible. But the first one was intended.)
    Stefan Ram, Apr 27, 2009
    #5
  6. Stefan Ram

    Ian Collins Guest

    Stefan Ram wrote:
    > Ian Collins <> writes:
    >>> public:
    >>> Account( double const balance );
    >>> double balance(); };

    >> No too big a deal here, but in general geters are a design smell.

    >
    > Yes, but I do not see a getter here. Let me explain why:
    >
    > I have quoted the public interface of the class above.
    >
    > It misses an important feature: documentation.
    >
    > So I will add that document now in the way the names suggest:
    >
    > - The constructor initializes a new account with
    > an opening balance as the argument.
    >
    > - The function »balance« returns the current balance
    > of the account.
    >
    > No mentioning of private fields in the documentation.
    >
    > So a client/caller/reader of this interface can not know
    > whether this function returns the value of a private field or
    > obtains the balance using some other means. He does not know
    > which fields an object of this class has. Therefore, I do not
    > deem »balance« to be a getter, just a non-void function.


    In that case, call it something like calculateBalance.

    --
    Ian Collins
    Ian Collins, Apr 27, 2009
    #6
  7. Stefan Ram

    Stefan Ram Guest

    Ian Collins <> writes:
    >In that case, call it something like calculateBalance.


    I deem that to be ugly. I still follow the advice Rob Pike
    gave 20 years ago:

    »Procedure names should reflect what they do;
    function names should reflect what they return.«

    Rob Pike; »Notes on Programming in C«; February 21, 1989

    http://www.lysator.liu.se/c/pikestyle.html

    Also, this is consistent with ISO/IEC 14882:2003(E), where in
    <cmath>, the function is named »::std::sin«, not »::std::calculateSin«.

    Also, either »calculate« has no meaning at all, or
    »calculateBalance« is /more/ transparent than »balance«,
    because it leaks the implementation detail that the result of
    this call is »calculated« - while »balance« alone is
    completely opaque, yielding no information whatsoever about
    the implementation, just stating what is returned.
    And exposing implementation details is exactly why getters
    are being criticized.
    Stefan Ram, Apr 27, 2009
    #7
  8. Stefan Ram

    Ian Collins Guest

    Stefan Ram wrote:
    > Ian Collins <> writes:
    >> In that case, call it something like calculateBalance.

    >
    > I deem that to be ugly. I still follow the advice Rob Pike
    > gave 20 years ago:
    >
    > »Procedure names should reflect what they do;
    > function names should reflect what they return.«
    >

    In the context of C++, what is a function and what is a procedure?

    --
    Ian Collins
    Ian Collins, Apr 27, 2009
    #8
  9. Stefan Ram

    Stefan Ram Guest

    Ian Collins <> writes:
    >>»Procedure names should reflect what they do;
    >>function names should reflect what they return.«

    >In the context of C++, what is a function and what is a procedure?


    Rob Pike wrote this in the context of C, where it might be
    asked as well.

    I assume that the terms stem from the Pascal culture.

    A Pascal procedure corresponds to a function not returning a
    value in C or C++.

    A Pascal function corresponds to a function returning a value
    in C or C++.

    There are functions, like »fopen« that return a value, but are
    still named for what they do. This expresses that the main
    purpose is deemed to be the action and the value is a
    secondary purpose (serving the main purpose by giving a
    feedback about the success of the attempted action).

    There are functions, like »rand« that have an effect, but
    still are named for what they return, because their result is
    deemed to be their main purpose, while their effect is deemed
    a secondary purpose. (The effect of »rand« is to advance the
    random number generator to the next state.)

    Naming is especially easy, when a function either only has an
    effect or only has a value. In the case of »fopen«, this
    separation can be done using OOP as follows:

    { FileOpenAttempt fileOpenAttempt( "source.txt", "r" );
    fileOpenAttempt.run();
    if( fileOpenAttempt.suceeded() )
    { FILE * file = fileOpenAttempt.result();
    use( file );
    file.close(); }
    else
    { ::std::cerr << fileOpenAttempt.report() << '\n'; }}

    Here, »run« is a pure action, while the other element
    functions only return a value, but do no action. This is akin
    to the structure of natural language, where phrases either
    express actions (verbal phrases) or things (noun phrases), but
    never both. Insofar, »if( fopen( ... ))« is somewhat
    unnatural, but one can get used to it.
    Stefan Ram, Apr 27, 2009
    #9
  10. Stefan Ram

    James Kanze Guest

    On Apr 27, 1:08 am, -berlin.de (Stefan Ram) wrote:
    > Ian Collins <> writes:
    > >>public:
    > >>Account( double const balance );
    > >>double balance(); };

    > >No too big a deal here, but in general geters are a design
    > >smell.


    > Yes, but I do not see a getter here. Let me explain why:


    > I have quoted the public interface of the class above.


    > It misses an important feature: documentation.


    > So I will add that document now in the way the names
    > suggest:


    > - The constructor initializes a new account with
    > an opening balance as the argument.


    > - The function »balance« returns the current balance
    > of the account.


    > No mentioning of private fields in the documentation.


    > So a client/caller/reader of this interface can not know
    > whether this function returns the value of a private field
    > or obtains the balance using some other means. He does not
    > know which fields an object of this class has. Therefore, I
    > do not deem »balance« to be a getter, just a non-void
    > function.


    I wonder if both you and Ian aren't confusing design level and
    implementation level a bit. From a design level, an Account
    certainly "hasA" balance (or currentBalance, or whatever), and
    that balance is a value, not a behavior. At the design level,
    some classes really are just glorified data containers, some are
    pure behavior, and some are a mixture of the two (although I
    find the latter occur fairly rarely). At the design level, I
    can't find anything to say against a class Account which
    contains a function balance() (or getBalance(), depending on the
    coding guidelines---but I prefer balance(), because it is
    logically an attribute).

    At the implementation level, of course, whether the class has a
    private member, which the function simply returns, or does
    something else, is irrelevant. (We use the function, rather
    than a public data member, precisely to keep it irrelevant.)

    > I would see a getter, if the documentation would read
    > instead:


    > - Each object of this class has a field named »balance_«.
    > The function »balance« returns the value of this field.


    Which is, precisely, an example of confounding an implementation
    detail and a design aspect (in this case, the contract). The
    class has an attribute balance. It may be implemented by a
    single private variable, or not. But that's none of the client
    code's business.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Apr 27, 2009
    #10
  11. On Apr 26, 11:59 pm, -berlin.de (Stefan Ram) wrote:
    >   For teaching purposes, I wrote this program as a first
    >   example of a definition of a class with non-static functions:
    >

    <snip - code>
    >   (End of program.)


    It is good you inserted this comment, because I nearly overlooked the
    closing brace of main.
    I hope you will give the closing braces more prominence in the code
    you present to the students, especially if the opening brace is not on
    the same line.

    >
    >   Regarding »acct.::Account::balance()«:
    >
    >   I was not aware that such a full qualification of a member
    >   function in a member function call was possible at all.
    >
    >   When would one need this? (To call an overloaded function
    >   of a base class?)


    You would only need it to disable the virtual-call mechanism. Calling
    the base-class implementation of a virtual function is the most common
    use.

    >
    >   Can the above definition of the class still be improved somehow?


    I would add two more member functions, to make the class more useful:
    void Account::deposit(double);
    void Account::withdraw(double);

    Otherwise, students will wonder what the use of an account is if any
    change to the balance requires you to create a new account.

    >
    >                             ~~
    >
    >   Is such an account class is a good example for teaching?


    Yes. It has a clear link to a real-world concept that the students
    will be familiar with and you can later revisit the Account class when
    dealing with more advances topics, like interaction between object.

    Bart v Ingen Schenau
    Bart van Ingen Schenau, Apr 27, 2009
    #11
  12. Stefan Ram

    James Kanze Guest

    On Apr 27, 2:17 am, Ian Collins <> wrote:
    > Stefan Ram wrote:
    > > Ian Collins <> writes:
    > >> In that case, call it something like calculateBalance.


    > > I deem that to be ugly. I still follow the advice Rob Pike
    > > gave 20 years ago:


    > > »Procedure names should reflect what they do;
    > > function names should reflect what they return.«


    > In the context of C++, what is a function and what is a
    > procedure?


    Should names be chosen "in the context of C++", or according to
    the design. In his case, "balance" is an attribute of the
    class; "balance()" is a function which returns the current
    value of that attribute. Regardless of how it is determined.
    (In such simple cases, of course, it's hard to imagine it being
    anything but a member variable, but in other cases... A complex
    number has four attributes, real part, imaginary part, modulus
    and argument, but I can't imagine an implementation actually
    storing all four as member variables.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Apr 27, 2009
    #12
  13. On Apr 27, 12:10 am, Ian Collins <> wrote:
    >
    > No too big a deal here, but in general geters are a design smell.


    I agree that getters are a design smell, but I did not see anything I
    would classify as a getter in Stefan's class.

    Regardless how you implement an Account class, one intrinsic property
    of an account is that it has a balance.
    Would you classify the function balance() in the following class also
    as a getter (and why)?

    class Account {
    private:
    double initialDeposit;
    std::vector<double> mutations;
    public:
    Account(double deposit) : initialDeposit(deposit) {}
    double balance()
    { return std::accumulate(mutations.begin(), mutations.end(),
    initialDeposit); }
    void deposit();
    void withdraw();
    };

    >
    > --
    > Ian Collins


    Bart v Ingen Schenau
    Bart van Ingen Schenau, Apr 27, 2009
    #13
  14. Stefan Ram

    James Kanze Guest

    On Apr 26, 11:59 pm, -berlin.de (Stefan Ram) wrote:
    > For teaching purposes, I wrote this program as a first
    > example of a definition of a class with non-static
    > functions:


    Several comments.

    > #include <iostream>
    > #include <ostream>


    The inclusion of <ostream> isn't necessary. It never was in
    practice, and the standard will require that it not be in the
    future. (I don't think this is really relevant to the pedagogic
    goals of the program, but IMHO, the less "unexplained magic" you
    throw at the students, the better.)

    > class Account
    > { private:
    > double balance_;
    > public:
    > Account( double const balance );
    > double balance();
    > };


    Several points:

    Formatting:
    I'd definitely put "private:" and "public:" on lines
    by themselves, and indented less than the rest---they're not
    lines like the others---they control what follows.

    Constructor:
    I'd declare it "explicit". I also wouldn't use the const in
    the parameter declaration---it's just comment, as far as the
    compiler is concerned, and has no relevance to the client
    code.

    Accessor:
    I'd definitely make balance() const.

    > ::Account::Account( double const balance )
    > { this->balance_ = balance; }


    There's no need for the this-> if the names are different.

    If you really want to encourage good practice, the member
    variable should be named balance, and the parameter
    initialBalance. Lot of people, including myself, don't always
    bother. Which makes some convention for differentiating the
    names important---I like myBalance and balance, but it's really
    a matter of style. (Except that a trailing underscore isn't
    very visible, and should probably be avoided.) But as a
    learning exercise, I think I'd stick with balance and
    initialBalance, rather than risk having to explain why I need a
    convention to differentiate the names.

    > double ::Account::balance()
    > { return this->balance_; }


    No need for the :: before Account, nor for the this->.
    Idiomatic C++ wouldn't use either.

    > int main()
    > { Account acct( 100 );
    > ::std::cout << acct.::Account::balance() << '\n';
    > ::std::cout << acct.balance() << '\n';
    > }


    Why both?

    > (End of program.)


    > Regarding »acct.::Account::balance()«:


    > I was not aware that such a full qualification of a member
    > function in a member function call was possible at all.


    > When would one need this? (To call an overloaded function of
    > a base class?)


    Using a qualified id has different semantics if the function is
    virtual; it suppresses dynamic lookup. It also ensures that
    lookup starts at the given class, and not in some derived class,
    e.g.:

    class DerivedAccount : public Account
    {
    public:
    double balance() { return 2.0 * Account::balance() ; }
    explicit DerivedAccount( double initialBalance )
    : Account( initialBalance )
    {
    }
    } ;

    DerivedAccount account( 42.0 ) ;
    std::cout << account.balance() << std::endl ; // displays 84
    std::cout << account.Account::balance() << std::endl ;
    // displays 42

    It's something I wouldn't present until much later, once the
    students have mastered inheritance.

    > Can the above definition of the class still be improved
    > somehow?


    See above. The main criticism I have is that there are parts
    that aren't at all idiomatic---using this->, for example, when
    not necessary, or making a parameter const (or a function which
    returns an attribute non-const).

    > ~~


    > Is such an account class is a good example for teaching?


    Probably. It lends itself to extension very well, e.g.
    functions like credit and debit. (Which in turn show why an
    attribute of a class is not a global variable.)

    > I need the first example to be very simple, yet it needs
    > to suggest to be useful and related to applications of
    > the language.


    > Are there any other good examples of classes, that are
    >
    > - small and simple
    > - not already part of the standard library
    > - not requiring special knowledge of a field
    > - looking somewhat natural and useful


    > ?


    > Account classes are used often.


    They also have the advantage of allowing an early introduction
    to the distinction of entity classes (Account) vs. values (the
    balance, etc.).

    > Sometimes, a class for complex numbers is used in teaching,
    > but such a class already is defined in the standard library
    > and might look too »mathematical«.


    On the other hand, it's a classical example of a class which has
    attributes which aren't directly represented by a member
    variable.

    > The only other topic that comes to my mind right now would
    > be a class for a compound date (YYYY, MM, DD) or time (HH,
    > MM) object.


    That will become very complicated, very quickly.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Apr 27, 2009
    #14
  15. Stefan Ram

    Stefan Ram Guest

    James Kanze <> writes:
    >> #include <iostream>
    >> #include <ostream>

    >The inclusion of <ostream> isn't necessary. It never was in
    >practice, and the standard will require that it not be in the
    >future. (I don't think this is really relevant to the pedagogic
    >goals of the program, but IMHO, the less "unexplained magic" you
    >throw at the students, the better.)


    (I would like to thank everyone for their responses, including
    authors of posts I have not directly replied to.)

    I remember this topic (<ostream>) from several other Usenet
    discussions, but I do not yet had knowledge that the
    forthcoming new C++ standard will clarify this. If someone
    knows about the specific locations where in the upcoming
    standard this was changed, so that I can look it up, I would
    be grateful for any hint.

    >>int main()
    >>{ Account acct( 100 );
    >> ::std::cout << acct.::Account::balance() << '\n';
    >> ::std::cout << acct.balance() << '\n';
    >>}

    >Why both?


    (Thanks for your comments, including those I have not quoted.)

    My usual approach in teaching is to show the most general
    maximally qualified notation first and then show any possible
    or common abbreviations. So above I wanted to show that both
    statements have the same behavior, here.

    >See above. The main criticism I have is that there are parts
    >that aren't at all idiomatic---using this->, for example,


    This follows the same idea: I start using the most explicit
    usage first (»this->balance_«), then I will explain that
    usually »this->« can be omitted and henceforth I will omit it
    indeed whenever possible.
    Stefan Ram, Apr 27, 2009
    #15
  16. James Kanze wrote:

    > I like myBalance and balance, but it's really a matter of style.
    > (Except that a trailing underscore isn't very visible, and should
    > probably be avoided.)


    Isn't leanness the point of the trailing-underscore convention? The
    knowledge of what's "mine" is not usually that hard to track once you
    have some idea of how a method operates (which is a prerequisite for
    doing anything to it); at least in the code I mostly read, almost all
    manipulated non-locals are members. So arguably the information
    should be there but not in yer face.

    Personally, I dislike any kind of prefix convention because it
    obscures the beginning of tokens, the most salient visual cue for
    word recognition. The obtrusion is grantedly slight but constant --
    though perhaps, being the kind that typos impress themselves on
    before subheadings, I'm more susceptible to the effect. I suppose the
    "m_" prefix minimizes this but a suffix is still more pleasant.


    Martin

    --
    Quidquid latine scriptum est, altum videtur.
    Martin Eisenberg, Apr 27, 2009
    #16
  17. Stefan Ram

    James Kanze Guest

    On Apr 27, 2:06 pm, -berlin.de (Stefan Ram) wrote:
    > James Kanze <> writes:
    > >> #include <iostream>
    > >> #include <ostream>

    > >The inclusion of <ostream> isn't necessary. It never was in
    > >practice, and the standard will require that it not be in the
    > >future. (I don't think this is really relevant to the
    > >pedagogic goals of the program, but IMHO, the less
    > >"unexplained magic" you throw at the students, the better.)


    > I remember this topic (<ostream>) from several other Usenet
    > discussions, but I do not yet had knowledge that the
    > forthcoming new C++ standard will clarify this. If someone
    > knows about the specific locations where in the upcoming
    > standard this was changed, so that I can look it up, I would
    > be grateful for any hint.


    In the same place it didn't say it before:). At the top of
    §27.3, there is a synopsis of the contents of the <iostream>
    header. In the orginal standard, only the eight standard
    objects are mentionned; in the current draft, there are also
    specific includes of <ios>, <streambuf>, <istream> and
    <ostream>.

    > >>int main()
    > >>{ Account acct( 100 );
    > >> ::std::cout << acct.::Account::balance() << '\n';
    > >> ::std::cout << acct.balance() << '\n';
    > >>}

    > >Why both?


    > My usual approach in teaching is to show the most general
    > maximally qualified notation first and then show any possible
    > or common abbreviations. So above I wanted to show that both
    > statements have the same behavior, here.


    Except that they don't, at least in general. In C++, a
    qualified id is used in this context to "turn off" virtualness,
    since there's no virtualness involved in your example, the
    qualification has no effect, but it certainly isn't the most
    general notation.

    > >See above. The main criticism I have is that there are parts
    > >that aren't at all idiomatic---using this->, for example,


    > This follows the same idea: I start using the most explicit
    > usage first (»this->balance_«), then I will explain that
    > usually »this->« can be omitted and henceforth I will omit it
    > indeed whenever possible.


    Hmmm. I'm not sure I agree. I'd start by saying that a name
    represents a class member (will be looked up as a class member
    first). The possibility of using this-> is simply a means of
    disambiguating the name, e.g. if it is masked by a local
    variable or parameter, or making it dependent in a template (but
    you don't think you want to get into that right away). I'm not
    sure I'd even present the notation until the need actually
    arised, but if I did, I'd certainly present the more usual
    notation simultaneously.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Apr 28, 2009
    #17
  18. Stefan Ram

    James Kanze Guest

    On Apr 27, 2:50 pm, Martin Eisenberg <> wrote:
    > James Kanze wrote:
    > > I like myBalance and balance, but it's really a matter of style.
    > > (Except that a trailing underscore isn't very visible, and should
    > > probably be avoided.)


    > Isn't leanness the point of the trailing-underscore convention? The
    > knowledge of what's "mine" is not usually that hard to track once you
    > have some idea of how a method operates (which is a prerequisite for
    > doing anything to it); at least in the code I mostly read, almost all
    > manipulated non-locals are members. So arguably the information
    > should be there but not in yer face.


    The information is superfluous. The only justification for it
    is that you have a poor naming convention, and end up with
    parameters and member variables that would otherwise have the
    same name. The use of a convention here is to create two
    different, distinctive names, not to encode some
    meta-information along the lines of Hungarian notation. And two
    different, distinctive names should be visually different; when
    you see the name used, you want to be able to immediately
    recognize which object is being referred to.

    > Personally, I dislike any kind of prefix convention because it
    > obscures the beginning of tokens, the most salient visual cue
    > for word recognition. The obtrusion is grantedly slight but
    > constant -- though perhaps, being the kind that typos impress
    > themselves on before subheadings, I'm more susceptible to the
    > effect. I suppose the "m_" prefix minimizes this but a suffix
    > is still more pleasant.


    The use of a prefix stems from the fact that in English,
    qualifiers preceded the qualified. Thus, we say "my status" and
    "initial status", and not "status my" and "status initial". So
    the member variable becomes "myStatus" and the argument to the
    constructor "initialStatus". (Variable names are qualified
    nouns, remember.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Apr 28, 2009
    #18
    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. Newsgroup - Ann
    Replies:
    5
    Views:
    587
    John Carson
    Jul 30, 2003
  2. slide_o_mix
    Replies:
    0
    Views:
    406
    slide_o_mix
    Oct 15, 2003
  3. Alex
    Replies:
    0
    Views:
    376
  4. Yakov
    Replies:
    1
    Views:
    90
    John W. Krahn
    Nov 12, 2006
  5. Andrew Falanga
    Replies:
    2
    Views:
    191
    Andrew Falanga
    Nov 22, 2008
Loading...

Share This Page