In this class we take a close look at some uses for constructors
and examine the C++ concept of I/O streams.
Copy constructor for Rational
// in the class definition (rational.h)
class Rational
{
private:
......
public:
......
Rational (const Rational&);
.....
};
// --------------------------------------------
// the implementation -- rational.C
Rational::Rational (const Rational& value)
: num (value.num), den (value.den)
{
// no code
}
QUESTION: Why MUST the argument to the copy constructor be a reference?
Constructors used for initialization
It's important to understand the difference between initialization and assignment.
Why??? -- different functions are called -- constructor or operator =
copy constructors are used whenever a new object is created
and initialized to an existing object of the same kind
* for creating copies of parameters for call-by-value
* for creating temporary objects for return-by value
* when explicitly called to initialize a new object from an existing object
Consider the following declarations -- what constructor(s) is(are) called?
Rational a;
Rational b(5);
Rational c (3, 7);
Rational d = c;
Rational e = Rational (1, 2);
Rational f = 6;
Constructors for type conversion
Sometimes it is necessary for the compiler to convert from one data type to another.
Example --
function f (double) is called as f(6). The compiler implicitly changes
the 6 to 6.0 and calls f as f(6.0).
We can do the same thing with classes. We can provide the means for the
compiler to change other data types into Rational objects.
Constructors with a single argument such as Rational (int) are used for conversion
Automatic type conversion using Rational(int) will be used
1. when you initialize a Rational object with an Int
Rational x = 7;
2. when you assign an int to a Rational
a = 6;
3. when you pass an int to a function expecting Rational
that's how z = y + 7; works
4. when a function that's declared to return Rational tries to return int
QUESTION: Can we convert Rational to int, double, etc.
ANSWER: Yes, if we provide the mechanism (not constructors) to do so.
See text pages 271 & 272 for discussion on how to do this.
I/O streams
No more printf, or output specifications
C++ uses the Unix concept of streams for all I/O.
What is a stream?
classes and instances in <iostream.h>
ostream -- a class for output stream
istream -- a class for input stream
cout, cerr -- instances of ostream for output
(replace stdout, stderr)
cin -- instance of istream for input (replaces stdin)
operator << -- insertion operator for output
operator >> -- extraction operator for input
operators are already overloaded for built-in types
ostream& operator<< (ostream& out, const& int)
The reference returned is to the ostream argument
we can overload these too
// a simple example of input/output from/to the console
#include <iostream.h>
main ()
{
int i;
double f = 5.3;
// get a value for i from cin
cin >> i;
// output values of i and f
cout << i;
cout << " ";
cout << f;
cout << endl;
}
Questions:
1. why don't we need address of 'i' in "cin >> i;"?
2. output could also be written as
cout << i << " " << f << endl;
Why is this possible?
Manipulators -- flush, endl, others (width, fill, precision,...)
see iomanip.h for details
Overloading ouput operator<<
It would be nice to be able to output any user-defined object using the
output operator <<. C++ allows us to do this with operator overloading
The first parameter to each operator<< function in the C++ library is a reference
to an "ostream". This is done to allow us to cascade the << operator like we did
in the example above. Therefore, whenever we overload operator<<, our return type
must also be ostream&.
Which ostream do we return a reference to?? -- the one that was passed in.
The function operator<< is typically defined to be a friend function.
class Rational
{
private:
int num, den;
public:
. . . .
friend ostream& operator<< (ostream& out, const Rational& r);
. . . .
}
ostream& operator<< (ostream& out, const Rational& r)
{
out << r.num << "/" << r.den;
return out;
}
Now when we can write
Rational X(4,5);
cout << X;
the output is 4/5
QUESTION:
Why can't operator<< be a member function of Rational (or any other object)?
ANSWER:
QUESTION:
What is the general form of the prototype for operator<< for any class ABC?
ANSWER:
QUESTION:
Why didn't we output an endl in our operator<< function?
ANSWER: