I l@ve RuBoard |
![]() ![]() |
4.10 Providing Class Instances of the iostream OperatorsOften, we wish to both read and write objects of a class. For example, to display our trian class object, we want to be able to write cout << trian << endl; To support this, we must provide an overloaded instance of the output operator: ostream& operator<<( ostream &os, const Triangular &rhs ) { os << "( " << rhs.beg_pos() << ", " << rhs.length() << " ) "; rhs.display( rhs.length(), rhs.beg_pos(), os ); return os; } We return the same ostream object passed into the function. This allows multiple output operators to be concatenated. Both objects are passed by reference. The ostream operand is not declared as const because each output operation modifies the internal state of the ostream object. The class object to be output, such as rhs, is declared as const because we are passing it by reference for efficiency rather than to modify the object itself. For example, given the object Triangular tri( 6, 3 ); the statement cout << tri << '\n'; generates ( 3 , 6 ) 6 10 15 21 28 36 Why is the output operator a nonmember function? A member function requires that its left operand be an object of the class. Were the output operator a member function, then the tri class object would need to be placed to the left of the output operator: tri << cout << '\n'; This would certainly confuse users of the class! The following input operator reads only the first four elements representing the Triangular class. The beginning position and its length are the only unique aspects of a Triangular class object. The actual element values are invariant; they are not stored within a particular class object. istream& operator>>( istream &is, Triangular &rhs ) { char ch1, ch2; int bp, len; // given the input: ( 3 , 6 ) 6 10 15 21 28 36 // ch1 == '(', bp == 3, ch2 == ',', len == 6 is >> ch1 >> bp >> ch2 >> len; // set the three data members of rhs ... rhs.beg_pos( bp ); rhs.length( len ); rhs.next_reset(); return is; } Here is a small program to test our input and output operators: int main() { Triangular tri( 6, 3 ); cout << tri << '\n'; Triangular tri2; cin >> tri2; // let's see what we got ... cout << tri2; } When compiled and executed, it generates the following output (my input is highlighted in bold):
( 3 , 6 ) 6 10 15 21 28 36
( 4 , 10 )
( 4 , 10 ) 10 15 21 28 36 45 55 66 78 91
Input operators are generally more complicated to implement because of the possibility of invalid data being read. For example, what if the left parenthesis was missing? For this example, I do not consider the possibility of invalid input. For a more realistic example of an input operator and a discussion of possible iostream error states, see [LIPPMAN98], Chapter 20. |
I l@ve RuBoard |
![]() ![]() |