120 likes | 132 Views
Stream I/O Operators and Friend Functions. Stream I/O Background. <iostream.h> contains declarations for classes istream ostream cin is an istream object cout is an ostream object. Stream I/O Background (continued).
E N D
Stream I/O Background • <iostream.h> contains declarations for classes • istream • ostream • cin is an istream object • cout is an ostream object
Stream I/O Background (continued) • C++ implements stream I/O by overloading the >> and << operators to allow integers, reals, and characters to be input from or output to a stream. (>> and << are really bit shift operators.) • Extraction operator (>>) use: istream_object >> object1 >> object2 >> … objectn; cin >> x >> y; • Insertion operator (<<) use: ostream_object << object1 << object2 << … objectn; cout << “Number = “ << num << endl; • >> and << return objects of type istream_object and ostream_object, respectively.
Overloading Stream I/O Operators • How can we read data into or write out the values of data types other than integer, floating point, or character? • Fraction • Vector • Set • Options: • Class methods, such as • Fraction Fraction::readFraction(); • Fraction Fraction::displayFraction(); • Write functions to further overload >> and <<
Overloading Stream I/O Operators (continued) • Syntax for overloading >> istream& operator >> (istream& is_name, class_name& object_name); • is_name is passed by reference because its state will be changed • object_name is passed by reference because data will be read into it • Syntax for overloading << ostream& operator <<(ostream& os_name, const class_name& object_name); • os_name is passed by reference because its state will be changed • object_name is a const because it will not be changed
Overloading Stream I/O Operators (continued) Fraction class example class Fraction { public: // constructors and other methods void setNumerator(int n); void setDenominator(int d); int getNumerator(); int getDenominator(); private: int numerator, denominator; }; istream& operator >>(istream& input, Fraction& f); ostream& operator <<(ostream& output, const Fraction& f);
Overloading Stream I/O Operators (continued) istream& operator >>(istream& input, Fraction& f) { char c; // to hold the ‘/’ separator int n, d; input >> n >> c >> d; if (d == 0) { cerr << “Zero denominator invalid” << endl; exit(1); } f.setNumerator(n); f.setDenominator(d); return input; }
Overloading Stream I/O Operators (continued) ostream& operator <<(ostream& output, const Fraction& f) { output << f.getNumerator() << ‘/’ << f.getDenominator(); return output; }
Friend Functions • A function can be defined to be a “friend” of a class: friend function-name(arguments); // inside of class definition • A friend function has direct access to the class’ private members, both data and methods • Making a function a friend can be convenient -- the class does not need “get” methods for the function to access its data • Using a friend function violates the rules of encapsulation. • Use friends only when absolutely necessary!
Friend Functions (continued) Fraction class using friends class Fraction { public: // constructors and other methods friend istream& operator >>(istream& input, Fraction& f); friend ostream& opeator <<(ostream& input, const Fraction& f); // set and get methods private: int numerator, denominator; }; istream& operator >>(istream& input, Fraction& f); ostream& operator <<(ostream& output, const Fraction& f);
Friend Functions (continued) istream& operator >>(istream& input, Fraction& f) { char c; // to hold the ‘/’ separator input >> f.numerator >> c >> f.denominator; // direct access if (f.denominator == 0) { cerr << “Zero denominator invalid” << endl; exit(1); } return input; }
Friend Functions (continued) ostream& operator <<(ostream& output, const Fraction& f) { output << f.numerator << ‘/’ << f.denominator; // direct access return output; }