490 likes | 495 Views
Learn about the concept of Abstract Data Types (ADTs) in programming, their implementation in C++, and practical examples using Rational ADT. Explore basic operations like addition, subtraction, multiplication, and division. Discover how to use default and copy constructors effectively.
E N D
CHAPTER 7Implementing abstract data types抽象数据类型实现 Introduction A data abstraction is a representation of information and the operations to be performed on the information. An abstract data type, or ADT, is a well-defined and complete data abstraction that uses the information-hiding principle. ADTs make it possible to create and manipulate objects in a natural manner. 数据抽象就是对信息表达并对信息执行的操作。抽象数据类型(ADT)按照信息屏蔽的原则,对数据抽象作意义明确完整的定义。ADT允许用自然的方法创建和管理对象。
7.1 INTRODUCING ABSTRACT DATA TYPES抽象数据类型简介 • Fundamental-type 基本数据类型 • Data abstraction 数据抽象 • Information-hiding 信息隐蔽 • Abstract data type(ADT) 抽象数据类型 Example, an Rational ADT : Rational a ( 1, 2 ) ; // a = 1 / 2 Rational b ( 2, 3 ) ; // b = 2 / 3 cout << a << “+” << b << “=” << ( a + b) << endl ;
Addition: • Mulitiplication: • Subtraction: • Division: 7.2 RATIONAL ADT BASICS有理数 Rational ADT 的基础 Our goal in developing Rational is to create a type whose objects are as natural to use as objects defined using the fundamental types. The basic arithmetic operations :
Class Rational • Data members: • numerator int object • denominator int object • Member functions: • Construct the rational number with default or particular attributes. • Add, subtract, multiply, and divide the rational number to another rational • number. • Copy the value of the rational number to another rational number. • Compare the rational number to another rational number. • Display the value of the rational number. • Extract the value of the rational number. • Inspect the values of the numerator and the denominator. • Set the values of the numerator and the denominator.
Rule minimality ( 最小化规则 ) • This rule states that unless a behavior is needed, it should not be part of • the ADT. • A corollary to the rule of minimality is the class minimality principle.
7.2.1 A client program using the rational library // Program 8.1 Demonstrate Rational ADT #include <iostream> #include <string> #include "rational.h" using namespace std ; int main() { Rational r , s ; cout << "Enter rational number (a/b): " ; cin >> r ; cout << "Enter rational number (a/b): " ; cin >> s ; Rational t ( r ) ; Rational Sum = r + s ; Rational Product = r * s ; cout << r << " + " << s << " = " << Sum << endl ; cout << r << " * " << s << " = " << Product << endl ; return 0; }
7.2.1 A client program using the rational library // Program 8.1 Demonstrate Rational ADT #include <iostream> #include <string> #include "rational.h" using namespace std ; int main() { Rational r , s ; cout << "Enter rational number (a/b): " ; cin >> r ; cout << "Enter rational number (a/b): " ; cin >> s ; Rational t ( r ) ; Rational Sum = r + s ; Rational Product = r * s ; cout << r << " + " << s << " = " << Sum << endl ; cout << r << " * " << s << " = " << Product << endl ; return 0; } Use the default constructor for the class Rational
7.2.1 A client program using the rational library // Program 8.1 Demonstrate Rational ADT #include <iostream> #include <string> #include "rational.h" using namespace std ; int main() { Rational r , s ; cout << "Enter rational number (a/b): " ; cin >> r ; cout << "Enter rational number (a/b): " ; cin >> s ; Rational t ( r ) ; Rational Sum = r + s ; Rational Product = r * s ; cout << r << " + " << s << " = " << Sum << endl ; cout << r << " * " << s << " = " << Product << endl ; return 0; } Use the copy constructor to create a new object.
7.2.1 A client program using the rational library // Program 8.1 Demonstrate Rational ADT #include <iostream> #include <string> #include "rational.h" using namespace std ; int main() { Rational r , s ; cout << "Enter rational number (a/b): " ; cin >> r ; cout << "Enter rational number (a/b): " ; cin >> s ; Rational t ( r ) ; Rational Sum = r + s ; Rational Product = r * s ; cout << r << " + " << s << " = " << Sum << endl ; cout << r << " * " << s << " = " << Product << endl ; return 0; } • copy constructor • The copy constructor has a single constant • reference parameter. • The copy constructor is always present : • It can be specified by designer • or is automatically supplied by the compiler.
7.2.1 A client program using the rational library // Program 8.1 Demonstrate Rational ADT #include <iostream> #include <string> #include "rational.h" using namespace std ; int main() { Rational r , s ; cout << "Enter rational number (a/b): " ; cin >> r ; cout << "Enter rational number (a/b): " ; cin >> s ; Rational t ( r ) ; Rational Sum = r + s ; Rational Product = r * s ; cout << r << " + " << s << " = " << Sum << endl ; cout << r << " * " << s << " = " << Product << endl ; return 0; } They use the copy constructor too.
7.2.1 A client program using the rational library // Program 8.1 Demonstrate Rational ADT #include <iostream> #include <string> #include "rational.h" using namespace std ; int main() { Rational r , s ; cout << "Enter rational number (a/b): " ; cin >> r ; cout << "Enter rational number (a/b): " ; cin >> s ; Rational t ( r ) ; Rational Sum = r + s ; Rational Product = r * s ; cout << r << " + " << s << " = " << Sum << endl ; cout << r << " * " << s << " = " << Product << endl ; return 0; } • Supply initialization parameters: • The parameter list. • The initialization expression.
7.2.1 A client program using the rational library // Program 8.1 Demonstrate Rational ADT #include <iostream> #include <string> #include "rational.h" using namespace std ; int main() { Rational r , s ; cout << "Enter rational number (a/b): " ; cin >> r ; cout << "Enter rational number (a/b): " ; cin >> s ; Rational t ( r ) ; Rational Sum = r + s ; Rational Product = r * s ; cout << r << " + " << s << " = " << Sum << endl ; cout << r << " * " << s << " = " << Product << endl ; return 0; } Overloaded operators
7.2.1 A client program using the rational library Assignment operator and copy construction Rational v ( 6, 21 ) ; // v is 6 / 21 Rational w ; // w is 0 / 1 w = v ; // w is 6 / 21 by assignment Rational x = v ; // x is 6 / 21 by copy construction Overloaded construction Rational x ( 3, 4 ) ; // v is 3 / 4 Rational y ( 5 ) ; // y is 5 / 1
7.2.1 A client program using the rational library const object // the data members can not be modified const Rational OneHalf ( 1, 2 ) ; Overloaded operators >> and << Rational r ; cout << "Enter rational number (a/b): " ; cin >> r ; cout << r ;
7.2.1 A client program using the rational library • If operator >> (or <<) is overloaded to be a member function, • left operand must be an object of Rational type : • Rational :: istream & operator >> ( istream &sin ) ; • Rational :: ostream & operator << ( ostream &sout ) ; • r >> cin ; • r << cout ; • If they overloaded to be common function or friend function, • we are free to define their left and right operands. • istream & operator >> ( istream &sin, const Rational &r ) ; • ostream & operator << ( ostream &sout, const Rational &r ) ; • cin >>r ; • cout << r ; const object // the data members can not be modified const Rational OneHalf ( 1, 2 ) ; Overloaded operators >> and << Rational r ; cout << "Enter rational number (a/b): " ; cin >> r ; cout << r ;
Function name 7.2.1 A client program using the rational library • Operators +, * are overloaded to be common function or friend function • Member function • Rational :: Rational operator + ( const Rational &r ) ; • Rational u ( 3, 4 ) , t ; • t = u + 2 ; // OK • t = 2 + u ;// Error • Common function or friend function • Rational operator + ( const Rational &r , const Rational &s ) ; • t = u + 2 ; // OK • t = 2 + u ; // OK
7.3 RATIONAL INTERFACE DESCRIPTION // rational.h: declaration of Rational ADT #ifndef RATIONAL_H #define RATIONAL_H #include <iostream> #include <string> using namespace std; // … #endif
// Rational ADT: class description class Rational { public: Rational(); // member functions default constructor Rational(int numer, int denom = 1); // a second constructor // some arithmetic and stream facilitators Rational Add(const Rational &r) const; Rational Multiply(const Rational &r) const; void Insert(ostream &sout) const; void Extract(istream &sin); protected: // inspectors int GetNumerator() const; int GetDenominator() const; // mutators void SetNumerator(int numer); void SetDenominator(int denom); private: // data members int NumeratorValue; int DenominatorValue; };
// Rational ADT: auxiliary operator description 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); #endif
7.3.1 Access restrictions 访问权限 publiccan be directly used protected can be use by other member functions of the class and by member functions from a derived class. private can be use only by other member functions of the class .
7.3.2 Constructor member functions The prototypes of the two Rational constructors Rational(); Rational(int numer, int denom = 1); A copy constructor and a member assignment operator are defaulted, the Rational class uses the definitions provided by the compiler.
7.3.3 Facilitator member functions 简化器 • Member functions: • Inspector functions(检查器) • provide methods to access representations of the date member. • Mutator functions(转变器) • provide methods to modify the representations of the data members. • Facilitator functions(简化器) • provide methods for achieving the operations intended with the object.
7.3.3 Facilitator member functions 简化器 Rational Add ( const Rational &r ) const ; Rational Multiply ( const Rational &r ) const ; void Insert ( ostream &sout ) const ; void Extract ( istream &sin ) ;
7.3.3 Facilitator member functions 简化器 Rational Add ( const Rational &r ) const ; Rational Multiply ( const Rational &r ) const ; void Insert ( ostream &sout ) const ; void Extract ( istream &sin ) ; • Const member functions can not change any of the invoking object’s data member. • Const member functions and operators can be used by const and non-const objects. • Non-const member functions con not be used by const objects.
7.3.3 Facilitator member functions 简化器 Rational Add ( const Rational &r ) const ; Rational Multiply ( const Rational &r ) const ; void Insert ( ostream &sout ) const ; void Extract ( istream &sin ) ; For example const Rational OneHalf ( 1, 2 ) ; OneHalf . Insert ( cout ) ; // legal OneHalf . Extract ( cin ) ;// illegal, Extract() is not const member function
Use the four Rational facilitators Rational r ; Rational s ; cout << "Enter rational number (a/b): " ; r.Extract ( cin ) ; cout << "Enter rational number (a/b): " ; s.Extract ( cin ) ; Rational t ( r ) ; Rational Sum = r.Add (s) ; Rational Product = r.Multiply (s) ; r.Inseral ( cout ) ; cout << " + " ; s.Inseral ( cout ) ; cout << " = " ; s.Inseral ( cout ) ; cout << endl ; r.Inseral ( cout ) ; cout << " * " ; s.Inseral ( cout ) ; cout << " = " ; Product.Inseral ( cout ) ; cout << endl ;
Use the four Rational facilitators Rational r ; Rational s ; cout << "Enter rational number (a/b): " ; r.Extract ( cin ) ; cout << "Enter rational number (a/b): " ; s.Extract ( cin ) ; Rational t ( r ) ; Rational Sum = r.Add (s) ; Rational Product = r.Multiply (s) ; r.Inseral ( cout ) ; cout << " + " ; s.Inseral ( cout ) ; cout << " = " ; s.Inseral ( cout ) ; cout << endl ; r.Inseral ( cout ) ; cout << " * " ; s.Inseral ( cout ) ; cout << " = " ; Product.Inseral ( cout ) ; cout << endl ; use Overloaded operators
Use the four Rational facilitators Rational r ; Rational s ; cout << "Enter rational number (a/b): " ; r.Extract ( cin ) ; cout << "Enter rational number (a/b): " ; s.Extract ( cin ) ; Rational t ( r ) ; Rational Sum = r.Add (s) ; Rational Product = r.Multiply (s) ; r.Inseral ( cout ) ; cout << " + " ; s.Inseral ( cout ) ; cout << " = " ; s.Inseral ( cout ) ; cout << endl ; r.Inseral ( cout ) ; cout << " * " ; s.Inseral ( cout ) ; cout << " = " ; Product.Inseral ( cout ) ; cout << endl ; cin >> r ; cin >> s ; Rational Sum = r + s; Rational Product = r * s; cout << r << " + " << s << " = " << Sum << endl; cout << r << " * " << s << " = " << Product << endl;
Use the four Rational facilitators Rational r ; Rational s ; cout << "Enter rational number (a/b): " ; r.Extract ( cin ) ;// cin >> r ; cout << "Enter rational number (a/b): " ; s.Extract ( cin ) ; // cin >> s ; Rational t ( r ) ; Rational Sum = r.Add (s) ;// Rational Sum = r + s; Rational Product = r.Multiply (s) ;// Rational Product = r * s; r.Inseral ( cout ) ; cout << " + " ; s.Inseral ( cout ) ; cout << " = " ; s.Inseral ( cout ) ; cout << endl ; // cout << r << " + " << s << " = " << Sum << endl; r.Inseral ( cout ) ; cout << " * " ; s.Inseral ( cout ) ; cout << " = " ; Product.Inseral ( cout ) ; cout << endl ; // cout << r << " * " << s << " = " << Product << endl;
7.3.4 Inspector member function 检查器 protected: int GetNumerator() const; int GetDenominator() const;
7.3.5 Mutator member function 转变器 protected: void SetNumerator(int numer); void SetDenominator(int denom);
7.3.6 Data member 数据成员 private: int NumeratorValue ; int DenominatorValue ;
7.3.6 Overloaded operators 运算符重载 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); Overloaded operators are the same as their conventional precedence and calling form . Exercise P423-12
7.4 IMPLEMENTING THE RATIONAL CLASS SCOPE OPERATOR (作用域运算符) void Rational :: SetNumerator(int numer) { NumeratorValue = numer; }
7.4.1 Constructor definitions // default constructor Rational::Rational() { SetNumerator(0); SetDenominator(1); } // (numer, denom) constructor Rational::Rational(int numer, int denom) { SetNumerator(numer); SetDenominator(denom); }
7.4.1 Constructor definitions // default constructor Rational::Rational() { SetNumerator(0); SetDenominator(1); } // (numer, denom) constructor Rational::Rational(int numer, int denom) { SetNumerator(numer); SetDenominator(denom); } Use member functions
7.4.1 Constructor definitions // default constructor Rational::Rational() { NumeratorValue = 0; DenominatorValue = 1; // (numer, denom) constructor Rational::Rational(int numer, int denom) { NumeratorValue = numer; if (denom != 0) DenominatorValue = denom; else DenominatorValue = 1; } // default constructor Rational::Rational() { SetNumerator(0); SetDenominator(1); } // (numer, denom) constructor Rational::Rational(int numer, int denom) { SetNumerator(numer); SetDenominator(denom); }
7.4.2 Inspector definitions // get the numerator int Rational::GetNumerator() const { return NumeratorValue; } // get the denominator int Rational::GetDenominator() const { return DenominatorValue; }
7.4.3 Mutator definitions // set the numerator void Rational :: SetNumerator(int numer) { NumeratorValue = numer; } // set the denominator void Rational :: SetDenominator(int denom) { if (denom != 0) { DenominatorValue = denom; } else { cerr << "Illegal denominator: " << denom<< "using 1" << endl; DenominatorValue = 1; } } Exception handling
7.4.4 Arithmetic facilitator definitions // adding Rationals Rational Rational::Add(const Rational &r) const { int a = GetNumerator(); int b = GetDenominator(); int c = r.GetNumerator(); int d = r.GetDenominator(); return Rational(a*d + b*c, b*d); } // multiplying Rationals Rational Rational::Multiply(const Rational &r) const { int a = GetNumerator(); int b = GetDenominator(); int c = r.GetNumerator(); int d = r.GetDenominator(); return Rational(a*c, b*d); } Rational x ( 1, 2 ) ; Rational y ( 1, 3 ) ; Rational z = x . Add ( y ) ; // 1/2 + 1/3 is 5/6 cout << z <<endl;
7.4.5 Insertion and extraction definitions Can you Output the value of x+y directly ? // inserting a Rational void Rational::Insert(ostream &sout) const { sout << GetNumerator() << '/' << GetDenominator(); return; } // extracting a Rational void Rational::Extract(istream &sin) { int numer; int denom; char slash; sin >> numer >> slash >> denom; SetNumerator(numer); SetDenominator(denom); return; } Rational x ; x . Extract ( cin ) ; Rational y ( 1, 3 ) ; Rational z = x . Add ( y ) ; z . Insert ( cout ) ;
7.4.5 Auxiliary arithmetic operator definitions // adding Rationals Rational operator+(const Rational &r, const Rational &s) { return r . Add ( s ) ; // is r + s } // multiplying Rationals Rational operator*(const Rational &r, const Rational &s) { return r . Multiply ( s ) ; // is r * s } Rational x ; x . Extract ( cin ) ; Rational y ( 1, 3 ) ; Rational z = x + y ; z . Insert ( cout ) ;
7.4.6 Auxiliary stream operator definitions // inserting a Rational ostream& operator<<(ostream &sout, const Rational &r) { r.Insert(sout); return sout; } // extracting a Rational istream& operator>>(istream &sin, Rational &r) { r.Extract(sin); return sin; } Rational x ; cin >> x ; Rational y ( 1, 3 ) ; Rational z = x + y ; cout << z << endl ;
7.5 COPY CONSTRUCTION, MEMBER ASSIGNMENT, AND DESTRUCTION // Rational : copy constructor Rational :: Rational ( const Rational &r ) { int a = r . GetNumerator() ; inr b = r . GetDenominator() ; SetNumerator(a) ; SetDenominator(b) ; } // Rational destructor Rational :: ~Rational ( ) { /* no body needed */ } Shallow copying (浅拷贝) The source’s data members are copied bit by bit to the corresponding data members of the target.
7.5 COPY CONSTRUCTION, MEMBER ASSIGNMENT, AND DESTRUCTION // Rational : copy constructor Rational :: Rational ( const Rational &r ) { int a = r . GetNumerator() ; inr b = r . GetDenominator() ; SetNumerator(a) ; SetDenominator(b) ; } // Rational destructor Rational :: ~Rational ( ) { /* no body needed */ } • Destructor • Cannot take a parameter. • Cannot produce a return value. • A class to a single destructor.
7.5 COPY CONSTRUCTION, MEMBER ASSIGNMENT, AND DESTRUCTION // Rational : assignment operator Rational & Rational :: operator= ( const Rational &r ) { int a = r . GetNumerator() ; inr b = r . GetDenominator() ; SetNumerator(a) ; SetDenominator(b) ; return *this ; }
Object . mf actual parameter ClassType :: mf formal parameter this About thispointer • this is a key word • this is a address of the object whose member function is being invoked. • this is imparted to the member function when is being invoked by system.
Object . mf actual parameter ClassType :: mf formal parameter this this &Object DM: FM: Object About thispointer • this is a key word • this is a address of the object whose member function is being invoked. • this is imparted to the member function when is being invoked by system. &Object Outside Inside Object *this Object.dm (*this).dm this->dm Object.fm (*this).fm this->fm * this
#include<iostream> #include<string> using namespace std; string s="w"; class C { public: C() //defual constructor { name=s; cout<<name<<": default constructed"<<endl; } C(const C &c) //copy constructor { name=s; cout<<name<<": copy constructor using "<<c.name<<endl; } ~C() // destructor { cout<<name<<": destructed "<<endl; } C & operator=(const C &c) // assignment { cout<<name<<": assigned using "<<c.name<<endl; return *this; } private: string name; //data member }; int main(){ C w; s="x"; C x; { s = "y" ; C y ; } s = "z" ; C z(w) ; x = w = z ; return 0 ; } w: default constructed x: default constructed y: default constructed y: destructed z : copy constructor using w w: assigned using z x : assigned using w z: destructed x: destructed w: destructed