Re: An kind of member function name scope specification
On Apr 26, 11:59 pm, r...@zedat.fu-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 =BBacct.::Account::balance()=AB:
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 =BBmathematical=AB.
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:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34