480 likes | 497 Views
CSCE 210 Data Structures and Algorithms. Prof. Amr Goneid AUC Part R1. ADTs as Classes. ADTs as Classes. Class Definition: Private & Public Members Constructors & Destructor Data and Function Members Accessors & Mutators Polymorphism and Overloading Example: Rational Numbers Class
E N D
CSCE 210Data Structures and Algorithms Prof. Amr Goneid AUC Part R1. ADTs as Classes Prof. Amr Goneid, AUC
ADTs as Classes • Class Definition: Private & Public Members • Constructors & Destructor • Data and Function Members • Accessors & Mutators • Polymorphism and Overloading • Example: Rational Numbers Class • Example: Simple String Class Prof. Amr Goneid, AUC
1. Class Definition: Private & Public Members • Classes use the technique of information hiding to avoid incorrect use of the class. This is done by creating two areas: a public area, and a private area public: Member Functions Outside World private: Data members Prof. Amr Goneid, AUC
Private & Public Members • External world has no access to the private area. • Users are allowed to operate on the objects of the class only via public member functions. • All member functions of a class have automatic access to all of the data members of that class. • Once we make a member variable a private member variable, there is then no way to change its value except by using one of the member functions. Prof. Amr Goneid, AUC
Class Definition • A class definition contains only the prototype for its member functions and the definitions of the data members. • It is declared in a class header file (.h) • The implementations for the member functions are given elsewhere, in a class implementation file (.cpp) not in the header file . • These two files form the Class Library. Prof. Amr Goneid, AUC
General Format of a Class Declaration (in Header File) class ClassName { public: function prototypes of methods and data members that are public and can be used by statements outside the class definition. private: prototypes of functions and type definitions and variable declarations of data members that are private and can be used only by statements inside the class definition. }; // a semicolon must appear here Prof. Amr Goneid, AUC
Class Library Files • The name of the header file is the class name followed by “.h “ , e.g. ClassName.h • The name of the implementation file matches that of the header file with an extension of “.cpp”, e.g. ClassName.cpp • Application programs using the class are called“client programs”. • These programs must include: #include “ClassName.h” #include “Classname.cpp” Prof. Amr Goneid, AUC
2. Constructors and Destructors Two special functionsin the public partwith the same name as the class: • The constructor is used to create and initialize objects declared to be of that class • There could be more than one constructor to allow for different ways of initializing objects. • The destructor is used to remove the objects (specially when the data is allocated dynamically). Only one destructor is allowed. Prof. Amr Goneid, AUC
3. Data & Function Members: Example Header File //File: Time.h Time Class Header File #ifndef TIME_H// used to avoid multiple definitions #define TIME_H // not part of the class class Time { public: Time(); // constructor, a must ~Time(); // destructor // Function prototypes void setTime (int, int, int); void displayTime (); const private: int hour, minute, second; }; // a semicolon must appear here #endif// TIME_H #include “Time.cpp" Function cannot change private members Prof. Amr Goneid, AUC
Implementing Member Functions • A member function is implemented in the implementation file (.cpp). The format is: <type> <class name> :: <function name> (param list) {..function body ..} • The Scope resolution operator: • :: prefix for each member function • Informs the compiler that the function is • a member of the class Prof. Amr Goneid, AUC
Example Implementation File //File: Time.cpp Time Class Implementation File #include <iostream> using namespace std; Time :: Time() { hour = minute = second = 0; } Time::~Time() { } // do nothing void Time :: setTime(int h, int m, int s) { hour = (h >= 0 && h < 24) ? h : 0; minute = (m >= 0 && m < 60) ? m : 0; second = (s >= 0 && s < 60) ? s : 0; } void Time :: displayTime() const { cout << hour << “:“ << minute << “:“ << second << endl; } Prof. Amr Goneid, AUC
Objects • Object: a particular instance of the class. • To declare an object in a client program: The same way we declare a variable but with the type = class name, e.g. Time t1; Time T[20]; This will also invoke the constructor. • The Dot Operator allows an object to access its public members, e.g. t1.displayTime(); Prof. Amr Goneid, AUC
Example of Application (Client) File //File: TimeAppl.cpp Time Class Application File #include “Time.h“ #include <iostream> using namespace std; int main() { Time t1 , t2; cout << “Start Time is: “; t1.displayTime ( ); t2.setTime (5, 10, 30); cout << “End Time is: “; t2.displayTime ( ); return 0; } Prof. Amr Goneid, AUC
Remarks • Every class should have a default constructor (without parameters). • The default constructor may also be implemented as: Time ::Time( ) : hour(0), minute(0), second(0) { } When used in the application program as: Time t1; then t1.hour, t1.minute and t1.second will be set initially to zero member initializers Prof. Amr Goneid, AUC
Remarks • An explicit value constructor may also be added and defined as: Time( int , int , int); and is implemented as: Time :: Time( int h, int m, int s) { hour = h; minute = m; second = s; } We can use it in the application to initialize an object: Time t1(7,45,0); • const functions cannot modify private data members Prof. Amr Goneid, AUC
4. Accessors and Mutators • It is possible to extract a private data member using an accessor function. For example, to access “hour”: int getHour( ) const; // Prototype int Time::getHour( ) const // function definition { return hour; } Time t1; int h = t1.getHour( ); // invoking the function • A mutator member function (like setTime( )) will be able to change the private data members. Prof. Amr Goneid, AUC
5. Polymorphism & Overloading • Defining several functions with the same name is called function overloading • The presence of more than one constructor for the class is an example of function overloading. • Polymorphism is what allows functions with the same name to do different things based on its arguments Prof. Amr Goneid, AUC
6. Example: ADT rational Abstraction: A rational number (fraction) is a rational representation of two integers (x,y). Elements or Members: A numerator (x) and a denominator (y), both are integers. (y) cannot be zero Relationship: The representation is equivalent to x / y Prof. Amr Goneid, AUC
ADT rational (continued) Fundamental Operations: • Read a fraction from keyboard • Display a fraction on the screen • Add Fractionsf = f1 + f2 (e.g. ½ + ¼ = ¾) • Subtract Fractionsf = f1 – f2 (e.g. ½ - 1/3 = 1/6) • Multiply Fractionsf = f1 * f2 (e.g. ½ * ¾ = 3/8) • Divide Fractionsf = f1 / f2 (e.g. 1/5 / ¼ = 4/5) • Reduce Fractions(e.g. 2/6 = 1/3) Prof. Amr Goneid, AUC
Implementing a rational Class We will have 3 files: • “rational.h” to contain the class definition. • “rational.cpp” to contain the implementation of the member functions. • “RationalTest.cpp” an application file to test the class. Prof. Amr Goneid, AUC
The Header File: rational.h // File: rational.h // Rational class definition #ifndef RATIONAL_H // used to avoid multiple definitions #define RATIONAL_H // not part of the class class rational { public: // Member functions // Constructors rational(); // Default Costructor rational(int); // Initialize numerator with denom = 1 rational(int, int); // Initialize both numerator and denom. Prof. Amr Goneid, AUC
The Header File: rational.h (cont.) void setNum(int); // Set numerator and denominator void setDenom(int); rational multiply(const rational &f); // Multiply fractions rational divide(const rational &f); // Divide fractions rational add(const rational &f); // Add Fractions rational subtract(const rational &f); // Subtract Fractions void readRational(); // Read a fraction void displayRational() const; // Display a fraction rational reduce() const; // Reduce fraction // Accessors int getNum() const; int getDenom() const; Prof. Amr Goneid, AUC
The Header File: rational.h (cont.) // Operator Style // Add object to parameter rational operator + (const rational &); // Test equality of object and parameter bool operator == (const rational &); private: // Data members (attributes) int num; // private data field int denom; // private data field }; // Note -- a class definition MUST end with a semicolon #endif // RATIONAL_H #include "rational.cpp" Prof. Amr Goneid, AUC
The Implementation File: rational.cpp // File: Rational.cpp // Rational class implementation #include <iostream> using namespace std; // Member functions // Constructors rational::rational() // Default Costructor { num = 0; denom = 0; } rational::rational(int n) // Class Constructor { num = n; denom = 1; } rational::rational(int n, int d) // Class Constructor { num = n; denom = d; } Prof. Amr Goneid, AUC
The Implementation File: rational.cpp // Set numerator and denominator void rational::setNum(int n) { num = n; } void rational::setDenom(int d) { denom = d; } // Multiply fractions rational rational::multiply(const rational &f) { rational temp(num * f.num, denom * f.denom); return temp; } // Divide fractions rational rational::divide(const rational &f) { rational temp(num * f.denom, denom * f.num); return temp; } Prof. Amr Goneid, AUC
The Implementation File: rational.cpp // Add fractions rational rational::add(const rational &f) { rational temp(num * f.denom + f.num * denom, denom * f.denom); return temp; } // Subtract Fractions rational rational::subtract(const rational &f) { rational temp(num * f.denom - f.num * denom, denom * f.denom); return temp; } Prof. Amr Goneid, AUC
The Implementation File: rational.cpp // Read a fraction void rational::readRational() { char slash; // storage for / do { cout << "Enter numerator / denominator: "; cin >> num >> slash >> denom; } while (slash != '/'); } // Display a fraction void rational::displayRational() const { cout << num << '/' << denom; } Prof. Amr Goneid, AUC
The Implementation File: rational.cpp // Reduce rational rational rational::reduce() const { int n,m,rem,gcd; // Get the two integers n = abs(num); m = abs(denom); while (n > 0) { rem = m % n; m = n; n = rem; } gcd = m; rational g (num/gcd, denom/gcd); return g; } Prof. Amr Goneid, AUC
The Implementation File: rational.cpp // Accessors int rational::getNum() const { return num; } int rational::getDenom() const { return denom; } // Operator-Like rational rational::operator + (const rational &f2) { rational temp (num * f2.denom + f2.num * denom, denom * f2.denom); return temp; } bool rational::operator == (const rational &f) { return (num == f.num && denom == f.denom); } Prof. Amr Goneid, AUC
Remarks • It is possible to create a temporary class object within a member function and initialize it using a constructor, e.g. rational rational::multiply(const rational &f) { rational temp (num * f.num, denom * f.denom); return temp; } • A regular C++ operator can be “overloaded” to perform a different action on class objects. A member function can be defined to do this. If is an operator, the prototype will be: <type> operator (parameter); e.g. bool operator == (const rational &); Prof. Amr Goneid, AUC
Remarks • The definition will be: <type> <ClassName>::operator (parameter); e.g. bool rational::operator == (const rational &f) { return (num == f.num && denom == f.denom); } For example: rational a , b; An expression of the form (a == b) will be evaluated as: (a.num == b.num) && (a.denom == b.denom) Prof. Amr Goneid, AUC
The Application File: RationalTest.cpp // File: RationalTest.cpp // Tests the rational class #include <iostream> #include "rational.h“ using namespace std; int main() { rational f1, f2; rational f3; // Read two rational numbers cout << "Enter 1st fraction:" << endl; f1.readRational(); cout << "Enter 2nd fraction:" << endl; f2.readRational(); Prof. Amr Goneid, AUC
The Application File: RationalTest.cpp // Fraction Arithmetic f3 = f1.multiply(f2); f1.displayRational(); cout << " * "; f2.displayRational(); cout << " = "; f3.displayRational(); cout << " = "; f3 = f3.reduce(); f3.displayRational(); cout << endl; f3 = f1.divide(f2); f1.displayRational(); cout << " / "; f2.displayRational(); cout << " = "; f3.displayRational(); cout << " = "; f3 = f3.reduce(); f3.displayRational(); cout << endl; Prof. Amr Goneid, AUC
The Application File: RationalTest.cpp f3 = f1.add(f2); f1.displayRational(); cout << " + "; f2.displayRational(); cout << " = "; f3.displayRational(); cout << " = "; f3 = f3.reduce(); f3.displayRational(); cout << endl; f3 = f1 + f2; // uses operator “+” for addition f1.displayRational(); cout << " + "; f2.displayRational(); cout << " = "; f3.displayRational(); cout << " = "; f3 = f3.reduce(); f3.displayRational(); cout << endl; Prof. Amr Goneid, AUC
The Application File: RationalTest.cpp f3 = f1.subtract(f2); f1.displayRational(); cout << " - "; f2.displayRational(); cout << " = "; f3.displayRational(); cout << " = "; f3 = f3.reduce(); f3.displayRational(); cout << endl; return 0; } Prof. Amr Goneid, AUC
Sample Run of RationalTest.cpp Enter 1st fraction: Enter numerator / denominator: 2/6 Enter 2nd fraction: Enter numerator / denominator: 3/8 2/6 * 3/8 = 6/48 = 1/8 2/6 / 3/8 = 16/18 = 8/9 2/6 + 3/8 = 34/48 = 17/24 2/6 + 3/8 = 34/48 = 17/24 2/6 - 3/8 = -2/48 = -1/24 Press any key to continue Prof. Amr Goneid, AUC
7. Example: Simple String Class Here we build a simple string class to do few tasks on our own string objects, e.g. read, write, get the character at a given location, etc. We implement the string as a dynamic array of characters. We will have 3 files: • “simpleString.h” to contain the class definition. • “simpleString.cpp” to contain the implementation of the member functions. • “simpleStringTest.cpp” an application file to test the class. Prof. Amr Goneid, AUC
The Header File: simpleString.h // File simpleString.h // Simple string class definition #ifndef SIMPLESTRING_H #define SIMPLESTRING_H class simpleString { public: // Member Functions // Constructors simpleString(); simpleString(int ); // Destructor ~simpleString(); Prof. Amr Goneid, AUC
The Header File: simpleString.h // Function Prototype definition // Read a simple string void readString(); // Display a simple string void writeString() const; // Retrieve the character at a specified position // Returns the character \0 if position is out of bounds char at(int) const; // Return the string length int getLength() const; // Return the string capacity int getCapacity() const; // Get the contents into an array void getContents(char[ ]) const; Prof. Amr Goneid, AUC
The Header File: simpleString.h private: // Data members (attributes) // maximum size int capacity; // pointer to a dynamic storage array char *s; // current length int length; }; #endif //SIMPLESTRING_H #include "simpleString.cpp" Prof. Amr Goneid, AUC
The Implementation File: simpleString.cpp // File: simplestring.cpp // Simple string class implementation #include <iostream> using namespace std; // Member Functions... // default constructor, capacity = 255 simpleString::simpleString() { s = new char[255]; capacity = 255; length = 0; } // Constructor with argument, capacity is mVal simpleString::simpleString(int mVal) { s = new char [mVal]; capacity = mVal; length = 0;} // Class Destructor simpleString::~simpleString() { delete [ ] s;} Prof. Amr Goneid, AUC
The Implementation File: simpleString.cpp // Read a simple string void simpleString::readString() { char next; int pos = 0; cin.get(next); while ((next != '\n') && (pos < capacity)) { // Insert next in array contents s[pos] = next; pos++; cin.get(next); } length = pos; } Prof. Amr Goneid, AUC
The Implementation File: simpleString.cpp // Write a simple string void simpleString::writeString() const { for (int pos = 0; pos < length; pos++) cout << s[pos]; } // Character at (pos). Returns \0 if position is out of bounds char simpleString::at(int pos) const { const char nullcharacter = '\0'; if ((pos < 0) || (pos >= length)) { cerr << "position " <<pos << " not defined." << endl; return nullcharacter; } else return s[pos]; } Prof. Amr Goneid, AUC
The Implementation File: simpleString.cpp // Return the string length int simpleString::getLength() const { return length; } // Return the string capacity int simpleString::getCapacity() const { return capacity; } // Get the contents into an array void simpleString::getContents(char str[ ]) const { for (int i = 0; i < length; i++) str[i] = s[i]; } Prof. Amr Goneid, AUC
The Application File:simpleStringTest.cpp // File: simpleStringTest.cpp // Tests the simple string class #include "simpleString.h“ #include <iostream> using namespace std; int main() { simpleString S1; simpleString S2(20); cout << S1.getCapacity() <<" "<<S1.getLength() << endl; cout << S2.getCapacity() <<" "<<S2.getLength() << endl; Prof. Amr Goneid, AUC
The Application File:simpleStringTest.cpp // Read in a string. cout << "Enter a string and press RETURN: "; S1.readString(); // Display the string just read. cout << "The string read was: "; S1.writeString(); cout << endl; // Display each character on a separate line. cout << "The characters in the string follow:" << endl; for (int pos = 0; pos < S1.getLength(); pos++) cout << S1.at(pos) << endl; return 0; } Prof. Amr Goneid, AUC
Sample Run of simpleStringTest.cpp 255 0 20 0 Enter a string and press RETURN: User Classes The string read was: User Classes The characters in the string follow: U s e r C l a s s e s Press any key to continue Prof. Amr Goneid, AUC
Learn on your own about: • Procedural vs. OOP • Translating a Library • Inline Functions • Overloading insertion and extraction operators • Conditional Compilation • Standard I/O Classes • The C++ String Class Prof. Amr Goneid, AUC