Abstract Data Types (ADTs)

149 Views

Download Presentation
## Abstract Data Types (ADTs)

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -

**Abstract Data Types (ADTs)**by Briana Morrison adapted from Dale/Weems/Headington and Cahoon/Davidson**Topics**• Abstraction • Abstract Data Types (ADTs) • Separate Compilation • Rational Class • Overloading Operators • Member function vs. non-member function • Good ADTs • Namespaces**Abstraction**• is the separation of the essential qualities of an object from the details of how it works or is composed • focuses on what, not how • is necessary for managing large, complex software projects**Control Abstraction**• separates the logical properties of an action from its implementation . . . Search (list, item, length, where, found); . . . • the function call depends on the function’s specification (description), not its implementation (algorithm)**Data Abstraction**• separates the logical properties of a data type from its implementation LOGICAL PROPERTIES IMPLEMENTATION What are the possible values? How can this be done in C++? What operations will be needed? How can data types be used?**Data Type**set of values (domain) allowable operations on those values FOR EXAMPLE, data type int has operations +, -, *, /, %, >>, << domain -32768 . . . 32767**Abstract Data Type (ADT)**• a data type whose properties (domain and operations) are specified (what) independently of any particular implementation (how) FOR EXAMPLE . . .**ADT Specification Example**TYPE TimeType DOMAIN Each TimeType value is a time in hours, minutes, and seconds. OPERATIONS Set the time Print the time Increment by one second Compare 2 times for equality Determine if one time is “less than” another**Another ADT Specification**TYPE ComplexNumberType DOMAIN Each value is an ordered pair of real numbers (a, b) representing a + bi. OPERATIONS Initialize the complex number Write the complex number Add Subtract Multiply Divide Determine the absolute value of a complex number**ADT Implementation means**• choosing a specific data representation for the abstract data using data types that already exist (built-in or programmer-defined) • writing functions for each allowable operation**“10” “45” “27”**10 45 27 Several Possible Representations of TimeType 3 int variables 3 strings 3-element int array • actual choice of representation depends on time, space, and algorithms needed to implement operations 10 45 27**class TimeType Specification**// SPECIFICATION FILE ( timetype.h ) class TimeType// declares a class data type {// does not allocate memory public : // 5 public function members void Set (int hours ,int mins , int secs ) ; void Increment ( ) ; void Write ( ) const ; bool Equal ( TimeType otherTime ) const ; bool LessThan (TimeType otherTime ) const ; private : // 3 private data members int hrs ; int mins ; int secs ; } ;**TimeType Class Instance Diagrams**currentTime endTime Set Set Private data: hrs mins secs Private data: hrs mins secs Increment Increment 18 30 0 17 58 2 Write Write LessThan LessThan Equal Equal**Client Code UsingTimeType**#include “timetype.h” // includes specification of the class using namespace std ; int main ( ) { TimeType currentTime ; // declares 2 objects of TimeType TimeType endTime ; bool done = false ; currentTime.Set ( 5, 30, 0 ) ; endTime.Set ( 18, 30, 0 ) ; while ( ! done ) { . . . currentTime.Increment ( ) ; if ( currentTime.Equal ( endTime ) ) done = true ; } ; }**Implementation File for TimeType**// IMPLEMENTATION FILE ( timetype.cpp ) // Implements the TimeType member functions. #include “ timetype.h” // also must appear in client code #include <iostream> . . . bool TimeType :: Equal ( /* in */ TimeType otherTime ) const // Postcondition: // Function value == true, if this time equals otherTime // == false , otherwise { return ( (hrs == otherTime.hrs) && (mins == otherTime.mins) && (secs == otherTime.secs) ) ; } . . .**timetype.h**client.cpp timetype.cpp client.obj timetype.obj client.exe Separate Compilation and Linking of Files specification file main program implementation file #include “timetype.h” Compiler Compiler Linker**Avoiding Multiple Inclusion of Header Files**• often several program files use the same header file containing typedef statements, constants, or class type declarations--but, it is a compile-time error to define the same identifier twice • this preprocessor directive syntax is used to avoid the compilation error that would otherwise occur from multiple uses of #include for the same header file #ifndef Preprocessor_Identifier #define Preprocessor_Identifier . . . #endif**Example Using Preprocessor Directive #ifndef**// timetype .h FOR COMPILATION THE CLASS DECLARATION IN // SPECIFICATION FILE FILE timetype.h WILL BE INCLUDED ONLY ONCE #ifndef TIME_H #define TIME_H // timetype .cpp // client.cpp // IMPLEMENTATION FILE // Appointment program class TimeType { #include “timetype.h” #include “timetype.h” public: . . .. . . int main ( void ) { private: . . . . . . } } ; #endif**Rational Abstract Data Type**• Consider Rational a(1,2); // a = 1/2 Rational b(2,3); // b = 2/3 cout << a << " + " << b << " = " << a + b; Rational s; // s = 0/1 cin >> s; cout << s << " * " << a << " = " << s * a; if (s == b) cout << “Equal” << endl; • Observation • Natural look that is analogous to fundamental-type arithmetic objects**Multiplication**Division Rational number Ratio of two integers: a/b Numerator over the denominator Standard operations Addition Subtraction Rational Number Review**Rational Number Representation**• Requirements • Represent a numerator and denominator • Implies in part a class representation with two int data members • NumeratorValue and DenominatorValue • Data members private to support information hiding • Public arithmetic behaviors (member functions) • Rational addition, multiplication and equality • Public relational behaviors • Equality and less than comparisons • Practice rule of class minimality**Rational Number Representation**• Other requirements • Public object behaviors • Construction • Default construction • Specific numerator and denominator construction • Assignment (provided automatically) • Value reading and printing • Inspection/accessors and mutation of data members • Clients deal with a Rational object!**Rational Number Representation**• Other requirements • Auxiliary operations (necessarily public) • Arithmetic, relational, reading, and printing operations • Provides the natural form we expect • Class definition provides a functional form that auxiliary operators use • Provides commutativity consistency • For C++ reasons 1 + r and r + 1 would not be treated the same if addition was a member operation**Rational Class Instance Diagrams**a b SetNumerator SetNumerator Add Add SetDenominator SetDenominator Multiply Multiply Private data: Numerator value Denominator value Private data: Numerator value Denominator value Print Print 2 3 1 2 Read Read LessThan LessThan Equal Equal Numerator Numerator Denominator Denominator**Consider**Rational r, s, Sum, Product; // requires default constructor cout << "Enter two rationals(a/b): " << endl; cin >> r >> s; // need I/O operations Sum = r + s; // need arithmetic operators Product = r * s; cout << r << " + " << s << " = " << Sum; cout << r << " * " << s << " = " << Product;**Class Rational Overview**class Rational { public: // for everybody including clients // for Rational member functions private: // for hidden Rational memberfunctions // for Rational data members } ;**Rational Private Section**private: // data members int NumeratorValue; int DenominatorValue;**Class Rational Interface**public: // default constructor Rational(); // specific constructor Rational(int numer, int denom = 1); // second argument is defaulted if not supplied // arithmetic facilitators Rational Add (const Rational &r) const; Rational Multiply (const Rational &r) const; bool Equal (const Rational &r) const;**Class Rational Interface Cont.**public cont. // stream facilitators void Print (ostream &sout) const; void Read (istream &sin); // inspectors int Numerator ( ) const; int Denominator ( ) const; // mutators void SetNumerator (int numer); void SetDenominator (int denom); };**Auxiliary Operator Prototyping**//after the class definition in rational.h Rational operator+ (const Rational &r, const Rational &s); Rational operator* (const Rational &r, const Rational &s); Rational operator== (const Rational &r, const Rational &s); ostream& operator<< (ostream &sout, const Rational &s); istream& operator>> (istream &sin, Rational &r);**Rational r;**Rational s; r.Read (cin); s.Read (cin); Rational t = r.Add (s); t.Print (cout); Rational r; Rational s; cin >> r; cin >> s; Rational t = r + s; cout << t; Natural look Should << be a member? Consider r << cout; Why Non-Member Operators**Const Power**const Rational OneHalf (1,2); cout << OneHalf; // legal cin >> OneHalf; // illegal**Remember**• Every class object • Has its own data members • Has its own member functions • When a member function accesses a data member • By default the function accesses the data member of the object to which it belongs! • No special notation needed • Auxiliary functions • Are not class members • To access a public member of an object, an auxiliary function must use the dot operator on the desired object object.member**Rational ADT Implementation**#include <iostream> using namespace std; // default constructor Rational::Rational ( ) { SetNumerator (0); SetDenominator (1); } • Example Rational r; // r = 0/1 Which objects arebeing referenced?**Specific Constructor**// (numer, denom) constructor Rational::Rational (int numer, int denom) { SetNumerator (numer); SetDenominator (denom); } • Example Rational u(2); // u = 2/1 (why?) Rational t(2,3); // t = 2/3 // we’ll be using t in future examples**Accessors / Inspectors**int Rational::Numerator ( ) const { return NumeratorValue; } int Rational::Denominator ( ) const { return DenominatorValue; } • Where are the following legal? int a = Numerator ( ); int b = t.Numerator ( ); Which object isbeing referenced? Why the const?**Numerator Mutator**void Rational::SetNumerator (int numer) { NumeratorValue = numer; } • Where are the following legal? SetNumerator (1); t.SetNumerator (2); Why no const?**Denominator Mutator**void Rational::SetDenominator (int denom) { if (denom != 0) DenominatorValue = denom; else { cerr << "Illegal denominator: " << denom << "using 1" << endl; DenominatorValue = 1; } } • Example SetDenominator (5);**Addition Facilitator**Rational Rational::Add (const Rational &r) const { int a, b, c, d; a = Numerator ( ); b = Denominator ( ); c = r.Numerator ( ); d = r.Denominator ( ); return Rational (a*d + b*c, b*d); } • Example cout << t.Add (u);**Multiplication Facilitator**Rational Rational::Multiply(const Rational &r) const { int a, b, c, d; a = Numerator ( ); b = Denominator ( ); c = r.Numerator ( ); d = r.Denominator ( ); return Rational (a*c, b*d); } • Example t.Multiply (u);**Equality Facilitator**bool Rational::Equal (const Rational &r) const { int a, b, c, d; a = Numerator ( ); b = Denominator ( ); c = r.Numerator ( ); d = r.Denominator ( ); return (a*d == b*c); } • Example t.Equal (u);**Print Facilitator**void Rational::Print (ostream &sout) const { sout << Numerator ( ) << '/' << Denominator ( ); return; } • Example t.Print (cout); • Why is sout a reference parameter?**Basic Read Facilitator**void Rational::Read (istream &sin) { int numer; int denom; char slash; sin >> numer >> slash >> denom; SetNumerator (numer); SetDenominator (denom); return; } • Example t.Read (cin);**Auxiliary Arithmetic Operators**Rational operator+ (const Rational &r, const Rational &s) { return r.Add (s); } Rational operator* (const Rational &r, const Rational &s) { return r.Multiply (s); } • Example cout << (t + t) * t;**Auxiliary Equality Operator**bool operator== (const Rational &r, const Rational &s) { return r.Equal (s); } • Example if (s == t) cout << “Equal” <<endl;**Auxiliary Output Operator**ostream& operator<< (ostream &sout, const Rational &r) { r.Print (sout); return sout; } • Why a reference return? • Note we can do either t.Print (cout); cout << endl;// unnatural cout << t << endl;// natural**Auxiliary Input Operator**istream& operator>> (istream &sin, Rational &r) { r.Read (sin); return sin; } • Why a reference return? • We can do either t.Read (cin); // unnatural cin >> t; // natural**Overloading Operators Rules**1. At least one argument must be of class type 2. May be a friend function 3. Cannot create a new operator 4. Cannot change the number of arguments for operator 5. Cannot change the precedence of operator 6. Cannot overload the following operators: • . (member selector) • :: (scope resolution) • .* (member indirection) • ?: (conditional if)**Separate Compilation Components**• Header file • Define class and prototype library functions • rational.h • Rational class implementation • Define member functions • rational.cpp • Auxiliary function implementations • Define assisting functions that provide expected but non-member capabilities • rational.cpp • Usage or Application File • Contains main()**Rational ADT Header File**• File layout • Class definition and library prototypes nested within preprocessor statements • Ensures one inclusion per translation unit • Class definition proceeds library prototypes #ifndef RATIONAL_H #define RATIONAL_H class Rational { // … }; // library prototypes …