Using Classes Classes and Function Members

advertisement
Using Classes
Classes and Function Members
Review
We’ve seen that the iostream library provides
the objects cin, cout and cerr:
These objects were not originally provided in
C++, but were added to the language using
its class mechanism.
Classes
The C++ class mechanism allows a user to add
new types to the language.
Bell Labs’ Jerry Schwarz used this to create:
• an istream class, to define the object cin; and
• an ostream class, to define cout and cerr.
The resulting I/O system was so elegant,
it was incorporated into the language.
Classes (ii)
Another class that was added ‘after the fact’ is
the string class, which provides a convenient
way to store and operate on sequences of
characters.
The string library provides the type string, plus
an assortment of useful string-processing
operations.
String Objects
Objects of type string are indexed variables,
meaning that each character in the variable can be
accessed via an index or subscript:
string name = “John Q. Doe”;
name
J
o
h
n
0
1
2
3
4
Q
.
5
6
7
D
o
e
8
9
10
Use the subscript operator to access individual chars:
char firstInitial = name[0];
// firstInitial == ‘J’
Dynamic string Objects
Objects of type string can grow and shrink as
necessary to store their contents:
string name = “John Q. Doe”;
name
J
o
h
n
0
1
2
3
4
// name.size() == 11
Q
.
5
6
name = “Philleas Fogg”;
name
7
D
o
e
8
9
10
// name.size() == 13
P
h
i
l
l
e
a
s
0
1
2
3
4
5
6
7
8
F
o
g
g
9
10
11
12
Some string Operations
Operation
read a word from an istream
read a line from an istream
find the length of the string
find if a string is empty
access the char at index i
concatenate two strings
access a substring of a string
insert a substring into a string
remove a substring
find a substring in a string
compare two strings
...
string function
istream >> str;
getline(istream, str);
str.size()
str.empty()
str[i]
str1 + str2
str.substr(Pos, NumChars)
str.insert(Pos, SubStr);
str.remove(Pos, NumChars);
str.find(Pattern, StartPos)
str1 == str2
(or !=, <, >, <=, >=)
Discussion
Some string operations are “normal” functions:
getline(cin, aString);
Other string operations are function members:
aString.size();
Function members are “messages” that class objects
“understand” and to which they respond...
For example, aString “knows” how big it is,
so when it receives the size() message,
it responds with the appropriate answer.
Function Members
Where a “normal” function is an external agent that
acts upon an object, a function member is a
message that elicits an internal response from the
object receiving it.
Examples:
getline(cin, aString);
// getline() acts on aString
if (aString.empty())
// ask aString, “are you empty?”
if (cin.good())
// ask cin, “are you good?”
In this sense, class objects are “more intelligent”
than regular char, int, double, ... objects.
Classes
Most classes provide a rich set of operations that
can be used to manipulate objects of the class.
To use a class effectively, you must know what
kinds of functions (“normal” and member) are
available to operate on objects of that class.
Otherwise, you risk spending much of your time
“reinventing the wheel.”
Example
Suppose a problem requires me to find the
position of a particular character within a string.
I can either write/call my own function to do so...
int PositionOf(char ch; string str)
{
for (int i = 0; i < str.size(); i++)
if (str[i] == ch)
return i;
}
return -1;
...
int pos = PositionOf(myChar, aString);
Example (ii)
... or I can ask aString to locate myChar for me,
using the string function member named find():
int pos = aString.find(myChar, 0);
Which is less work?
• Writing your own is more work to code, test and
debug, and the result is less flexible than find().
• Using find() requires awareness (i) that the function
member exists, and (ii) of how to use it.
Discussion
Be aware of the functionality a class provides
(but don’t memorize the nitty-gritty details).
Know where (in a reference book) to look up
the operations a class supports.
Then, when a problem involves an operation
on a class object, scan the list of operations
looking for one that you can use
-- don’t reinvent the wheel!
Example
The text provides a RandomInt class.
Objects of this class are integers with
“random” values, which can be used to
simulate all sorts of “random” occurrences.
#include “RandomInt.h”
...
RandomInt die1(1,6), die2(1,6);
// two dice
die1.Generate(); die2.Generate()
// roll the dice
cout << “dice roll = “
<< die1 + die2 << endl;
// display results
RandomInt Objects
The range of random values is specified when an
object is declared:
#include “RandomInt.h”
...
const int HEADS = 0,
TAILS = 1;
RandomInt coin(HEADS,TAILS);
coin.Generate();
// flip coin
cout << coin << endl;
// display result
RandomInt Operations
Operation
RandomInt function
Display a RandomInt
ostream << randInt
Declare a RandomInt
RandomInt name;
Declare a RandomInt
within range first..last
RandomInt name(first, last);
Generate new random value
randInt.Generate();
Generate new random value
from
range first..last
randInt.Generate(first, last);
Add two RandomInt values
randInt1 + randInt2
(also -, *, /)
Compare two RandomInt values randInt1 == randInt2
(also !=, <, >, <=, >=)
Sample Program
#include <iostream>
// cin, cout
using namespace std;
#include “RandomInt.h”
// RandomInt class
int main()
{
const int HEADS = 0, TAILS = 1;
// for readability
RandomInt coin(HEADS, TAILS);
// model a coin
int numHeads = 0, numTails = 0;
// counters
for (int i = 1; i <= 10000; i++) // loop 10,000 times
{
coin.Generate();
// flip coin
if (coin == HEADS)
// count
numHeads++;
//
heads
else
// vs. tails
numTails++;
}
cout << “\nIn 10,000 tosses of a coin,\n”
<< “ heads occurred “ << numHeads << “ times\n”
<< “ and tails occurred << numTails << “ times”
<< endl;
}
Other Classes
As mentioned earlier, cin and cout are objects
of the istream and ostream classes,
respectively.
To use these classes effectively, you must be
aware of the range operations available for
them...
Some istream Operations
istream function
cin >> ch;
cin.get(ch);
cin.good()
cin.bad()
cin.fail()
cin.clear();
cin.ignore(n, ch);
Description
Extract next non-whitespace character
from cin and store it in ch.
Tell cin, “Put your next character
(whitespace or not) into ch.”
Ask cin, “Are you in good shape?”
Ask cin, “Is something wrong?"
Ask cin, “Did the last operation fail?”
Tell cin, “Reset yourself to be good.”
Tell cin, ignore the next n characters,
or until ch occurs, whichever comes first.
Some ostream Operations
ostream function
cout >> expr
cout.put(ch);
cout << flush
cout << endl
cout << fixed
cout << scientific
cout << showpoint
Description
Insert expr into cout.
Tell cin, “Insert ch into yourself.”
Write contents of cout to screen.
Write a newline to cout and flush it.
Display reals in fixed-point notation.
Display reals in scientific notation.
Display decimal point and trailing zeros
for real whole numbers.
cout << noshowpoint Hide decimal point and trailing zeros
for real whole numbers.
More ostream Operations
ostream function
Description
cout << showpos
Display sign for positive values.
cout << noshowpos
Hide sign for positive values.
cout << boolalpha
Display true, false as “true”, “false”.
cout << noboolalpha
Display true, false as 1, 0.
cout << setprecision(n) Display n decimal places for reals.
cout << setw(w)
Display next value in field width w.
cout << left
Left-justify subsequent values.
cout << right
Right-justify subsequent values.
cout << setfill(ch)
Fill leading/trailing blanks with ch.
Summary
Well-designed classes provide a rich set of operations
that make them useful for many problems.
Operations can be external (normal functions),
or internal (function members) to the class.
Function members act as messages to class objects.
To use a class effectively, you must know
• what capabilities the class provides; and
• how to use those capabilities.
Download