// stuVector.cpp // Introduction to operator overloading // Student and StudentVector classes // Demonstrates the sort function from the standard library #include #include #include #include #include #include #include // sort() using namespace std; #include "range.h" class Student { public: Student() { } Student( const string & id, const string & lname ) { m_ID = id; m_LastName = lname; } bool operator <(const Student & S2) const // overloads the less than operator { return (m_ID < S2.m_ID); } bool operator ==(const Student & S2) const // overloads the equality operator { return m_ID == S2.m_ID; } friend ostream & operator <<(ostream & out, const Student & S ) // overload the stream output operator { out << S.m_ID << " " << S.m_LastName << "\n"; return out; } friend istream & operator >>(istream & inp, Student & S) // overload the stream input operator { inp >> S.m_ID >> S.m_LastName; return inp; } private: string m_ID; string m_LastName; }; // define a StudentVector class that acts as a "wrapper" around // a vector object. class StudentVector { public: // constructor that sets the capacity StudentVector(int capacity = 0) { vStudents.reserve( capacity ); } // adds a new student to the collection void add(const Student & S) { vStudents.push_back(S); } const Student & at( int j ) const { return vStudents.at( j ); } Student & at( int j ) { return vStudents.at( j ); } vector::iterator getBegin( ) { return vStudents.begin( ); } vector::iterator getEnd( ) { return vStudents.end( ); } // Returns a modifiable reference to a student. Permits // the collection to be modified. Throws RangeError. Student & operator [](unsigned j) { if( j < 0 || j >= vStudents.size( ) ) throw RangeError( __FILE__, __LINE__, j ); return vStudents[ j ]; } // Returns a constant reference to a student. This is // useful when a collection is declared const. // Throws RangeError. const Student & operator [](unsigned j) const { if( j < 0 || j >= vStudents.size( ) ) throw RangeError( __FILE__,__LINE__,j ); return vStudents[ j ]; } int size() const { return vStudents.size(); } // overloads the stream output operator friend ostream & operator <<(ostream & out, const StudentVector & vec) { vector::const_iterator I = vec.vStudents.begin( ); while( I != vec.vStudents.end( ) ) { out << *I; I++; } return out; } private: vector vStudents; }; //*************** TESTING THE CLASSES ********************** void Example1() { StudentVector sVec; // Demonstrate two ways to throw an exception: // 1. vector class default exception // 2. our own RangeError exception try { //cout << sVec.at( 0 ); //cout << sVec[0]; } catch( const exception & e ) { cout << e.what( ) << endl; } sVec.add( Student ( "555-33-2222","Davis" ) ); sVec.add( Student ( "222-33-4444","Adams" ) ); sVec.add( Student ( "444-33-0000","Baker" ) ); cout << "The collection:" << endl; cout << sVec << endl; try { // subscript operator returns a modifiable reference // to a student in the collection. Use this to modify // its contents. sVec[0] = Student( "222-33-4444","Impostor" ); // subscript also returns a const reference: const Student s3 = sVec[1]; cout << "The collection:" << endl; cout << sVec << endl; // at() is overloaded. It can return a reference: sVec.at(1) = Student( "000-00-0000","Nobody" ); // or it can return a const reference: cout << "At index 1: " << sVec.at( 1 ) << endl; // Throws RangeError exception: cout << sVec[5] << endl; } catch( const RangeError & R ) { cout << R; } catch( ... ) { cout << "Unknown exception thrown.\n"; } } void Example2( ) // iterators, sorting. { StudentVector sVec( 10 ); sVec.add( Student ( "444-33-0000","Baker" ) ); sVec.add( Student ( "555-33-2222","Davis" ) ); sVec.add( Student ( "222-33-4444","Adams" ) ); sVec.add( Student ( "333-44-1111","Smith" ) ); sVec.add( Student ( "300-33-0000","Jones" ) ); // Must define operator < for the vector objects // before calling sort: sort( sVec.getBegin( ), sVec.getEnd( ) ); cout << "Sort by Student ID:" << endl; cout << sVec << endl; } int main() { Example1( ); //Example2( ); return 0; }