logistics
play

Logistics Project IOStreams III Part 2 (water) due Sunday, Oct 16 - PDF document

Logistics Project IOStreams III Part 2 (water) due Sunday, Oct 16 th Feedback by Monday Part 3 (block) due Sunday, Oct 30 Inserters and Extractors, Questions? Manipulators, and friends Exam Exam 2 Exam 2 What


  1. Logistics • Project IOStreams III – Part 2 (water) due Sunday, Oct 16 th • Feedback by Monday – Part 3 (block) due Sunday, Oct 30 Inserters and Extractors, • Questions? Manipulators, and friends Exam Exam 2 • Exam 2 • What it will cover – Thursday, October 27. – C++ classes • constructors • Inheritance • Operator overloading – Review Session – Templates • Tuesday, Oct 25 th / 9-10am (70-3435) – STL • Wednesday, Oct 26 th / 8-9pm (70-3445) – Memory Management Logistics Plan for this week • Final exam • I/O Week – Good news…bad news – Today: IOStreams 1 – Good news – Tomorrow: IOStreams 2 • Last day of finals, November 18 th – Thursday: IOStreams 3 – Bad news • Friends • 8am-10am • Review of inserters/extractors • Manipulators (FYI) – Room • 01-3338 1

  2. IOStream Class Hierarchy Insertion and Extraction • Recall: – Insertion and Extraction is the standard means for writing / reading data and objects to / from text form. • Insertion (output) – operator<< • Extraction (input) – operator>> int i = 5; cout << i; cin >> i; Insertion and Extraction Insertion and Extraction int i=5; • Inserters and extractors for built-in datatypes (like int, double, float , double d = 7.0; etc.) are predefined member functions of the myClass foo (7); IOStream classes. • It would be nice if we can do I/O on objects cout << i << d << foo; of our own classes in the same manner as the basic datatypes. Insertion and Extraction Insertion and Extraction Signature • Since the operators are being defined • We can do so by overloading the outside of a class, the operator will take the operator>> and operator<< for our classes. 2-argument form: istream & operator>> (istream &is, myClass& m); • Note: these operators must be defined ostream & operator<< (ostream &os, myClass& outside of any class. m); Very often, these operators will need access to private members of myClass thus are usually declared as friend . Note that the operators return a reference to the stream acted upon. 2

  3. Sidebar: friend Example • By using friend , a class can grant access to class date { non-member functions or to another class. public: date (int d, int m, int y); • Friend functions can be declared anywhere within date(); a class declaration, but it is common practice to private: int day; list friends at the beginning of the class. int month; int year; • The public and protected keywords do not apply to friend functions friend istream &operator>> (istream& is, date& d); friend ostream &operator<< (ostream& os, date &d); }; Using existing operators Friends and inheritance • The simplest approach is to decompose your class • You cannot have virtual friend into a set of objects/variables that have inserters functions. and extractors defined. friend istream &operator>> (istream& is, date& d) { is >> d.day >> d.month >> d.year; return is; } friend ostream &operator<< (ostream& os, date &d) { os << d.day << ‘ ‘ << d.month << ‘ ‘ << d.year; return os; } This is why operators are declared as friends Friends and inheritance Friends and inheritance class Performer Musician M (“Ringo”) { public: cout << “Info on the drummer for the Beatles: “ << M; Performer (char *name, char *talent); virtual void calculatePay(); friend ostream &operator<< (ostream& os, Performer &P) Calls operator<< (ostream& os, Performer &P) } class Musician : public Performer displays only Performer data. { public: Musician (char *name); void calculatePay(); } 3

  4. Friends and inheritance Friends and inheritance class Performer ostream &operator<< (ostream& os, Performer &P) { { public: return P.display (os); Performer (char *name, char *talent); } virtual void calculatePay(); virtual ostream &display(ostream &out); Musician M (“Ringo”) friend ostream &operator<< (ostream& os, Performer &P) cout << “Info on the drummer for the Beatles: “ << M; } class Musician : public Performer { Calls operator<< (ostream& os, Performer &P) public: Musician (char *name); calls Musician::display void calculatePay(); displays only Musician data. virtual ostream &display(ostream &out); } Friend classes Friend classes // Forward declaration of friend class. • A class can declare a member function of class PointCollection; another class as a friend // Point class. class Point • A class can declare an entire other class as a { friend PointCollection; friend. public: Point(const double x, const double y); ~CPoint(void) • Useful where one class is tightly coupled to // ... another class. private: double x; double y; }; Friend classes Friend classes void PointCollection::set(const double x, const • Friendship is not mutual double y) { // Get the number of elements in the void Point::illegallyAccessCollection (PointCollection collection. PC, int i) const int nElements = vecPoints.size(); { cout << “Point “ << i << “ is “<< // Set each element. PC.vecPoints[i]; for(int i=0; i<nElements; i++) } { vecPoints[i].x = x; vecPoints[i].y = y; } } 4

  5. Friend classes Friends • Friendship is not transitive • Questions? – Will not travel down class heirarchy // Forward declaration of friend class. class PointCollection; // Point class. class Point { friend PointCollection; // subclasses of PointCollection cannot access // Point’s data members public: Point(const double x, const double y); ~CPoint(void) // ... private: double x; double y; }; Using existing operators Writing an inserter ( operator<< ) • Good safety tip: 1. The first argument should be a reference to an ostream . The second argument should be a constant – It is usually a good idea to make extraction and reference to your class. insertion complementary operations. The function should return a reference to an ostream 2. so that insertions can be chained. – Thus, 3. The body of the function should perform whatever date d (10, 10, 2003); output is appropriate for your class, but nothing more! date dd; 4. If you need to access the private data members of your cout << d; class directly, then your class must declare this function cin >> dd; to be a friend // dd == d Writing an inserter ( operator<< ) Writing an extractor ( operator>> ) friend ostream &operator<<( ostream &out, const • Like inserter except: Point &p ) – Must handle possible errors { out << ’(’ << p.x << ’,’ << p.y << ’)’; – Argument cannot be const reference. return out; – Almost surely will have to declare as a } friend . Output: (0,0) 5

  6. Writing an extractor ( operator>> ) Writing an extractor ( operator>> ) friend istream &operator>> (istream &in, Point &p) • Things to note: { char c; – Checks to see if in same format as output. int ok = FALSE; – Stops reading as soon as an error is found. in >> c; if (c == ‘(‘)) { – Sets failbit if format is not correct. in >> p.x >> c; if (c == ‘,’) { in >> p.y >> c; if (c == ‘)’) ok = TRUE; } } • Questions? if (!ok) in.clear (in.rdstate() | ios::failbit return in; } Inserters / Extractors Manipulators • Questions • What’s the deal with manipulators? cout << setw(5) << setfill (‘0’) << 345; How does C++ know what to do with setw and set_fill Manipulators Manipulators • The iostreams have a version of operator<< • Example: and operator>> that take a function pointer – cout << flush as an argument: – Note that there is a non-member function ostream & operator<< (ostream& (*f)(ostream&)) { return (*f)(*this); } ostream & flush (ostream& os) { return os.flush(); } 6

  7. Manipulators Manipulators When the compiler sees: • Let’s kick it up a notch cout << flush; It will convert to cout.operator<< (flush); • What if your manipulator takes arguments? cout << setw(5) << 123; Which will call flush (cout) Which will result in There is no operator<< with a function pointer cout.flush(); and an argument And all this is done at compile time!! Manipulators Manipulator class smanip • functor!!! { public: ostream & (*f) (ostream &os, int); // function to call int intarg; // integer argument • Recall: what differentiates functors from smanip (ostream & (*ff)(ostream&, int), int ii) : pointers to function is that functors are f (ff), intarg(ii) {} ostream& operator(ostream &os) { return (*f)(os, intarg); objects } } – They can retain state. ostream& operator<< (ostream& os, smanip& sm) { return sm(os); } Manipulator Manipulator When the compiler sees: • Assume there is a non-member function cout << setw(5); It will convert to ostream & setw (ostream& os, int w) //lets call smanip (setw, 5), setsm cout << smanip (setw, 5); { then cout.operator<< (setsm); return os.width(w); Which will call } setsm(cout); Which will result in setw(os, 5) smanip setw(int i) Which will call { os.setw(5); return smanip(setw, i); And all this is done at compile time!! } 7

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend