Turns out to be very useful in some more advanced and mathematical work. I had to use a class with one these functions to be able to integrate certain statistical probability density functions.
Not in CS201.
8.4.7 Friend functions as operators -- CS202
Not in CS201.
8.4.8 Type conversion operators -- CS202
Not in CS201.
8.5 Static Members -- worth knowing about now
You have already met constructors. Because constructors make
objects they have to be able to work without having any objects!
So they are automatically static.
Static data members are shared by all objects. They are a good place to put information that all (or many) objects need to know and share.
Static member functions should be used when you have to do something inside a class but don't have an object to do it to.
How to draw static things in the UML
They are usually underlined or have a dollar sign put in front of them.
You usually have a check box to click to get this effect in most tools.
They are called static or class-wide.
Example of static members in Practice
One of the commonest uses for static data members is keeping track of
what objects exist. So suppose we are working for Universal Widgets
and need to keep track of widgets then we will need
class Widget;All widgets have a serial number that is used to identify each Widget:
class Widget
{
int id;
//...more data
};And when we construct a new Widget we need to give it the next number:
Widget::Widget()
{
id = next_number;
next_number++;
print_sticky_bar_code_label();//id encoded in label
//...
}BUT, what is next_number, where do we store it, how many are there, and who should control it?
Exercise: How do we declare it? See answer2 below.
Now the software we are writing is going to get these serial numbers re-input through a bar-code scanner at various points of manufacture and selling.... so we need a function that will find the Widget that has a particular id. Since this must tell us where an object is (rather than just giving as a copy of it) we need a function to return a pointer to a Widget:
static Widget* find(int id) { return *(widget[id-1]); }
(I use id - 1 because arrays and vectors start at zero).
So, do we use a vector or an array to hold our widgets? And Why? See answer3 below.
Next.... where do we put our vector of Widget pointerss?
So we get a new static data member:
static int next_number;
static vector <Widget*> widget;Then after the declation of Widget we must initialize this static member:
int Widget::next_number=1;
vector <Widget*> Widget::widget;(which looks redundant but appears to be needed)
Then we can add a function to record each new Widget as it is created. We put:
widget.push_pack(this);in the Widget constructor above.
Here is what the above (and some other stuff) looks like in the UML.
. . . . . . . . . ( end of section Reading) <<Contents | End>>
Glossary
Note: I may rescale if nobody gets an "A".
When will the final be
[ schedule.html ]
Can we skip section 8.6 like the book says
Yes. Pelase read the web site above.
Give as a hint on what is ione the final
Look at the quizzes.
How do you distinguish and attribute from an operation
An attribute is some data. It does nothing.
An operation does something and is not data. It is a tiny little program.
Attributes are never shown with parentheses, opertaion are always shown in with parentheses.
In the UML: attributes are in the second compartment of a class and the operations are in the third and bottom compartment.
Where is i1 on pages 272 and 273 defined
See Page 261.
Where are the missing bits of Clock
Scattered thru the chapter. Why not look in
[ 16.html ]
for
[ clock.cpp ]
it is a lot easier than retyping it yourself!
How do I print a diagram in Dia on 1 or two pages
The File>> Page Setup menu gets you to a dialog. In the bottom left hand part
you can select "Fit to" 1 by 1. Then click the "OK" button. Typically
this makes the page fit the diagram a little too tightly, so I add a
line accross the top of the diagram and select the white color ("FFFFFF").
Another, simpler technique is to export the diagram as "png" and print the
result.
What is a query
A query is a UML function that gives you data about an object without
changing the object in any way. It is written as a stereotype like this
<<query>> getColor():ColorQueries are also called accessors and are coded in C++ with the "const" keyword
Color getColor() const { return color ;}
Why do we use classes -- they make a simple program complicated
We use classes becasue they make complex programs simpler. They
separate the concerns into different classes so we only have to
think about a small part of the problem at one time. We can also think
about the solution of the problem in terms that are used by our clients.
We can model the problem and make a visible connecion between the problem and
our code.
We also use them because they are the only way to do drive modern graphical user interfaces.
Finally there are some useful and powerful class libraries for certain
kinds of problem.
Can we create our own types with type conversions
Yes. There is one subtle problem that sometimes happens.... that is in
CSCI202.
What is the purpose of a function call operator
We use it when we need an object that works just like a normal function.
You can skip the rest of this answer....
I had a recent case of a student who had written a program to integrate functions of one variable. Here is how we used it:
cout << integrate( sin , 0, PI/4 ) << endl;
cout << integrate( exp , 0, 1 ) << endl;
cout << integrate( recip , 1, 20 ) << endl;(where we declared
double recip (double x) { return 1.0/x; }
)
Our problem was that we wanted to integrate this function with respect to x:
double chisq(double x, double f ) {return /*horrible*/; }
which has an extra parameter f the degrees of freedom.
So we defined a function object:
class ChiSq
{ double f;
public:
ChiSq(double f0=1):f(f0) {}
double operator()(double x) { return chisq(x, f); }
};And then wrote
cout << integrate( ChiSq(2) , 1, 2 ) << endl;
cout << integrate( ChiSq(3) , 1, 2 ) << endl;And it worked...
static Type data;
Type classname::data = value;
(define inline static member function):
static Type name(parameters){body}
(declare static member function):
static Type name(parameters);
Type classname::name(parameters){ body }
(answer2): make it static
static int next_number;and initialize it after the class like this:
int Widget::next_number=1;
(answer3): The number of widgets are increasing. So, it must be a vector!
(answer4): The vector of widgets is a property of the class not
of the program(global) or a particular object. Therefore it must be static
(or class-wide).
. . . . . . . . . ( end of section Answers to Exercises) <<Contents | End>>