Using Classes The C Classes and Function Members —

advertisement
Using Classes
Classes and Function Members —
An Introduction to
OOP (Object-Oriented Programming)
Chapter 7
The "++" in C++
1
Classes
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
— a major modification of C's struct.
This mechanism allows any programmer to
add new types to the language. They are
necessary to model real-world objects that have
multiple attributes; e.g., temperature.
2
Classname identifier;
object
An object is a program entity whose type is a
class. Their main difference from other things
we've been calling "program objects" is that in
addition to storing data values they also have
built-in operations for operating on this
data.
anObject
operations
data
3
Although objects can be processed by "shipping
them off" to functions for processing,
externalFunction(anObject)
they can also operate on themselves using their
built-in operations, which are functions. These
functions are called by means of the "push-button"
dot operator:
anObject.internalFunction(...)
We say that
. sends a message to anObject.
anObject
operations
internalFunction(...)
data
4
I/O Classes
Bell Labs’ Jerry Schwarz used the class mechanism
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 powerful and yet
easy to use that it was incorporated into the
language.
We will study these classes and the operations they
provide later after we look at another class provided
in C++.
5
The String Class
Read §7.4
carefully
C has a library of basic functions that can be used
to process strings, which are simply char arrays
(see slide #9).
C++ added a new string class that provides:
• an easy way to store strings, and
• a large assortment of useful built-in
string-processing operations.
Lab 7
To use the string type, we must
#include <string>
Warning: #include <string>
NOT
<cstring>
#include <string.h>
which is C's string-processing library
6
First one
used in Lab 7
Some string Operations
(others in §7.4)
Skip leading
white space;
read until next
white space;
leave it in
stream
Operation
read a word from input (e.g., cin)
read an entire line from input
string function
input >> str;
getline(instream, str);
find the length of string str
check if str is empty
access the char in str at index i
concatenate str1 and str2
compare str1 and str2
str.size()
Read all chars
str.empty()
up to but not
including the
str[i]
next newline
character;
str1 + str2
remove it
str1 == str2
from stream
(or !=, <, >, <=, >=)
str.substr(pos, numChars)
str.insert(pos, subStr);
str.remove(pos, numChars);
access a substring str
insert a substring into a str
remove a substring from str
find first occurrence of string aStr
in str starting at position pos
find first occurrence of any char of
string aStr in str starting at pos
Print out handy reference sheet in Lab 7
str.find(aStr, pos)
str.find_first_of(aStr, pos)
Constant string::npos is
returned for unsuccessful searches
7
Note that some string operations are "normal" functions:
getline(cin, aString);
They are external agents that act on objects.
Other string operations are internal agents — built-in function
members that determine how the object is to respond to
messages they receive. These messages are sent using the
("push button") dot operator.
aString.size();
For example, aString "knows" how big it is, so when it
receives the size() message via the dot operator, it responds
with the appropriate answer.
In a sense, class objects are "smarter" than regular char, int,
double, ... objects because they can do things for themselves.
The "I can do it myself"
principle of OOP
8
String Objects
Variables, such as string variables, whose data is stored
in an array (a sequence of items) are called
indexed variables because each individual item can be
accessed by attaching an index (also called a subscript),
enclosed in square brackets, to the variable's name: var[index].
For example, suppose name is declared by
string name = "John Q. Doe";
name's value is an array of 11 characters:
name
J
0
o
h
n
1
2
3
Q
4
5
.
6
7
D
o
e
8
9
10
Note that indexes
are numbered
beginning with 0.
Using the subscript operator []to access individual chars:
char firstInitial = name[0];
// firstInitial = 'J'
name[8] = 'R';
// last name -> Roe
9
Dynamic string Objects
Objects of type string can grow and shrink as necessary
to store their contents (unlike C-style strings):
// name.size() = 11
string name = "John Q. Doe";
name
J
o
h
n
0
1
2
3
Q
.
5
6
4
name = "Mary M. Smith";
name
M
a
r
y
0
1
2
3
4
D
o
e
8
9
10
7
// name.size() = 13
M
.
5
6
7
More examples:
string myName;
myName = "John Calvin";
myName = "Susie Doe";
S
m
i
t
h
8
9
10
11
12
myName.size()
0
11
9
10
Note: The diagram for the string object name on
the preceding slide is really not correct. It shows
only the data part of this object and not the built-in
operations. But to save space, we will usually show
only the string of characters that it stores.
name
A large number of built-in string operations like
those described on earlier slides — e.g.,
size()
empty()
insert()
find()
find_first_of()
find_last_of()
. . .
J
o
h
n
0
1
2
3
4
Q
.
5
6
7
D
o
e
8
9
10
11
Another C++ Class (Template)
Another C++ class you may find useful is for complex
numbers: complex<T>, where T may be float,
double, or long double.
Mathematically: a + bi
1.5 + 3.2i
i
C++: complex<T>(a,b)
complex<double>(1.5, 3.2)
complex<double>(0, 1)
Inputs
Outputs
(1.5, 3.2)
(1.5,3.2)
(0, 1)
(0, 1)
3.14
(3.14,0)
12
Figure 7.2 Quadratic Equation Solver — Complex Roots
/* This program solves quadratic equations using the
quadratic formula.
Input: the three coefficients of a quadratic equation
Output: the complex roots of the equation.
-----------------------------------------------------------*/
#include <iostream>
#include <complex>
using namespace std;
// cout, cin, <<, >>
// complex types
int main()
{
complex<double> a, b, c;
cout << "Enter the coefficients of a quadratic equation: ";
cin >> a >> b >> c;
complex<double> discriminant = b*b - 4.0*a*c,
root1, root2;
root1 = (-b + sqrt(discriminant)) / (2.0*a);
root2 = (-b - sqrt(discriminant)) / (2.0*a);
cout << "Roots are " << root1 << " and " << root2 << endl;
}
13
Sample runs:
Enter the coefficients of a quadratic equation: 1 4 3
Roots are (-1,0) and (-3,0)
Enter the coefficients of a quadratic equation: 2 0 -8
Roots are (2,0) and (-2,0)
Enter the coefficients of a quadratic equation: 2 0 8
Roots are (0,2) and (-0,-2)
Enter the coefficients of a quadratic equation: 1 2 3
Roots are (-1,1.41421) and (-1,-1.41421)
Enter the coefficients of a quadratic equation: (1,2) (3,4) (5,6)
Roots are (-0.22822,0.63589) and (-1.97178,-0.23589)
14
The I/O Classes
As we noted earlier, C++ provides an istream class
for processing input and an ostream class for
processing output and that
• cin is an object of type istream
• cout and cerr are objects of type ostream
To use these classes effectively, you must be aware of
the large collections of operations provided by them
(although like the string class, it really isn't feasible
to memorize all of them and how they are used.)
Read § 7.3 carefully; note the diagrams of
streams; note how I/O actually takes place.
15
Some ostream Operations
ostream function
 cout << expr
cout.put(ch);
cout << flush
 cout << endl
 cout << fixed
cout << scientific
 cout << showpoint
cout << noshowpoint
= default
Read §7.3
carefully
Description
Insert expr into cout
Tell cout, "Insert ch into yourself"
Write contents of cout to screen
Write a newline to cout and flush it
cout is
buffered;
cerr is
not.
Display reals in fixed-point notation
Display reals in scientific notation
Display decimal point and trailing zeros for
real whole numbers
Hide decimal point and trailing zeros for
real whole numbers
format manipulators
Once used, stay in effect
(except for setw())
16
More ostream Operations
ostream function
cout << showpos
cout << noshowpos
cout << boolalpha
cout << noboolalpha
cout << setprecision(n)
cout << setw(w)
cout << left
cout << right
cout << setfill(ch)
Read §7.3
carefully
Description
Display sign for positive values
Hide sign for positive values
Display true, false as "true", "false"
Display true, false as 1, 0
Display n decimal places for reals
Display next value in field of width w
Left-justify subsequent values
Right-justify subsequent values
Fill leading/trailing blanks with ch
#include <iomanip> for these
17
Example:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n1 = 111, n2 = 22;
double d1 = 3.0 , d2 = 4.5678;
char c1 = 'A', c2 = 'B';
cout << "1. " << n1 << n2 << d1 << d2 << c1 << c2 << endl;
cout << "2. " << n1 << " " << n2 << " " << d1 << " " << d2
<< " "<< c1 << " " << c2 << endl;
cout << fixed << showpoint << setprecision(2);
cout << "3. " << n1 << " " << n2 << " " << d1 << " " << d2
<< " " << c1 << " " << c2 << endl;
cout << "4. " << setw(5) << n1 << " " << n2 << " "
<< setw(8) << d1 << " " << setw(2) << d2 << " "
<< c1 << " " << c2 << endl;
Output:
1. 1112234.5678AB
-----------------------------2. 111 22 3 4.5678 A B
-----------------------------3. 111 22 3.00 4.57 A B
-----------------------------4.
111 22
3.00 4.57 A B
------------------------------
Rounds
Expands if
width too small
18
Some istream Operations
Tabs, spaces,
end-of-lines
istream function
cin >> var;
Description
cin.get(ch);
Tell cin, "Put your next character;
(whitespace or not) into ch."
Skip white space and extract
characters from cin up to the first one
that can't be in a value for var;
convert and store it in var.
Both are
used in
Lab 7
19
Examples (cont. from earlier):
cout << "> ";
cin >> n1 >> d1 >> n2 >> d2 >> c1 >> c2;
cout << "Output:\n"
<< n1 << " " << n2 << " " << d1 << " " << d2 << " "
<< c1 << " " << c2 << endl;
Input/Output:
> 1 2.2 3 4.4 A B
Output:
1 3 2.20 4.40 A B
--------------------
cin:
Input/Output:
> 1
2.2
3
4.4
A
B
Output:
1 3 2.20 4.40 A B
--------------------
cin:
1
2. 2
3
4. 4
A
B 
1  2 . 2 3  4 . 4  A  B 
Same as before
20
cout << "> ";
cin >> n1 >> d1 >> n2 >> d2 >> c1 >> c2;
cout << "Output:\n"
<< n1 << " " << n2 << " " << d1 << " " << d2 << " "
<< c1 << " " << c2 << endl;
Input/Output:
> 12.2 34.4AB
Output:
12 34 0.20 0.40 A B
--------------------
cin:
1 2. 2
3 4. 4A B 
cout << "> ";
cin >> d1 >> c1 >> n1 >> d2 >> c2 >> n2;
cout << "Output:\n"
<< n1 << " " << n2 << " " << d1 << " " << d2 << " "
<< c1 << " " << c2 << endl;
Input/Output:
> 12.2 34.4A5B
Output:
4 5 12.20 0.40 3 A
--------------------
cin:
1 2. 2
3 4. 4A 5 B
The character B is left in cin for the next input statement.
21
In the last example, a character was left in cin for the next input
statement. To see how this can cause problems, suppose the
following code came after the preceding example:
for (int i = 1; i <= 5; i++)
{
cout << "> ";
cin >> d1 >> c1 >> n1 >> d2 >> c2 >> n2;
cout << "Output:\n"
<< n1 << " " << n2 << " " << d1 << " " << d2 << " "
<< c1 << " " << c2 << endl;
}
When executed, the following output would be produced.
Execution would not pause to allow input of new values for the variables.
They retain their old values.
>
4
>
4
>
4
>
4
>
4
Output:
5 12.20
Output:
5 12.20
Output:
5 12.20
Output:
5 12.20
Output:
5 12.20
0.40 3 A
0.40 3 A
0.40 3 A
0.40 3 A
0.40 3 A
The following operations on
istreams like cin show how we
can recover from bad input.
22
More istream Operations
istream function
Description
cin.good()
Ask cin, "Are you in good shape?"
cin.bad()
Ask cin, "Is something wrong?"
 cin.fail()
Ask cin, "Did the last operation fail?"
 cin.clear();
Tell cin, "Reset yourself to be good."
 cin.ignore(n, ch);
Tell cin, ignore the next n characters, or
until ch occurs, whichever comes first.
23
Example showing how to read a valid real number:
double number;
Infinite Loop
while (true)
// or for(;;)
{ cout << "Enter a real number: ";
cin >> number;
if (cin.fail())
// input failure?
{
cerr << "\n** Non-numeric input!\n";
cin.clear();
// reset all I/O status flags
cin.ignore(80, '\n'); // skip next 80 input chars
}
// or until end-of-line char
else
break;
}
24
More info in §7.5
Random Numbers
Slides 25-30
are optional
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
25
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
26
RandomInt Operations
Operation
Display a RandomInt
Declare a RandomInt
Declare a RandomInt
within range first..last
Generate new random value
Generate new random value
from range first..last
Add two RandomInt values
(also -, *, /)
Compare two RandomInt values
(also !=, <, >, <=, >=)
RandomInt function
ostream << randInt
RandomInt name;
RandomInt name(first, last);
randInt.generate();
randInt.generate(first, last);
randInt1 + randInt2
randInt1 == randInt2
27
Figure 7.4 Simulate Shielding of a Nuclear Reactor
/* This program simulates particles entering the shield described in
the text and determines what percentage of them reaches the outside.
Input:
thickness of the shield, limit on the number of direction
changes, number of neutrons, current direction a neutron
traveled
Output: the percentage of neutrons reaching the outside
--------------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include "RandomInt.h"
// cin, cout, <<, >>
// random integer generator
int main()
{
int thickness,
collisionLimit,
neutrons;
cout << "\nEnter the thickness of the shield, the limit on the \n"
<< "number of collisions, and the number of neutrons:\n";
cin >> thickness >> collisionLimit >> neutrons;
28
RandomInt direction(1,4);
int forward,
collisions,
oldDirection,
escaped = 0;
for (int i = 1; i <= neutrons; i++)
{
// Next neutron
forward = oldDirection = collisions = 0;
while (forward < thickness && forward >= 0 &&
collisions < collisionLimit)
{
direction.generate();
if (direction != oldDirection)
collisions++;
oldDirection = direction;
if (direction == 1)
forward++;
else if (direction == 2)
forward--;
}
}
}
if (forward >= thickness)
escaped++;
cout << '\n' << 100 * double(escaped) / double(neutrons)
<< "% of the particles escaped.\n";
29
Sample runs:
Enter the thickness of the shield, the limit on the
number of collisions, and the number of neutrons:
1 1 100
26% of the particles escaped
Enter the thickness of the shield, the limit on the
number of collisions, and the number of neutrons:
100 5 1000
0% of the particles escaped
Enter the thickness of the shield, the limit on the
number of collisions, and the number of neutrons:
4 5 100
3% of the particles escaped
Enter the thickness of the shield, the limit on the
number of collisions, and the number of neutrons:
8 10 500
0.2% of the particles escaped
30
Read
Some Final Notes about Classes
Well-designed classes provide a rich set of
operations that make them useful for many
problems.
Operations can be external (normal) functions to
which objects are passed for processing; or they
may be internal function members of the class.
Function members receive messages to class
objects and determine the response.
31
Read
To use a class effectively, you must know what
capabilities the class provides; and how to use
those capabilities.
• 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!
32
/* translate.cpp is an English-to-Pig-Latin translator.
==> PUT YOUR USUAL OPENING DOCUMENTATION HERE:
==> COURSE AND SECTION, DATE
NAME,
Input: English sentences.
Precondition: Each sentence contains at least one word.
Output: The equivalent Pig-latin sentence.
---------------------------------------------------------------*/
#include <iostream>
#include <string>
using namespace std;
// cin, cout, <<, >>
// class string
//==> PUT YOUR PROTOTYPE OF FUNCTION englishToPigLatin() HERE
int main()
{
//==> PUT YOUR USUAL OPENING STATEMENT HERE TO OUTPUT//==> YOUR NAME, LAB #, COURSE AND SECTION INFO
cout << "Pig Latin translator.\n";
string englishWord, pigLatinWord;
char separator;
33
cout << "\nEnter an English sentence (xxx to stop):\n";
cin >> englishWord;
while (englishWord != "xxx")
{
separator = ' ';
while (separator != '\n')
{
pigLatinWord = englishToPigLatin(englishWord);
cout << pigLatinWord;
cin.get(separator);
if (separator != '\n')
cout << ' ';
else
{
cout << endl;
cout << "\nEnter next English sentence (xxx to stop):\n";
}
cin >> englishWord;
}
}
}
//==> PUT YOUR DEFINITION OF FUNCTION englishToPigLatin() HERE
1
2
34
Download