1 / 12

1 // Rational class interface: support operations for rationals 2 //

1 // Rational class interface: support operations for rationals 2 // 3 // CONSTRUCTION: with (a) no initializer, or (b) an integer 4 // that specifies the numerator, or (c) two integers 5 // specifying numerator and denominator, or 6 // (d) another Rational 7 //

Download Presentation

1 // Rational class interface: support operations for rationals 2 //

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 1 // Rational class interface: support operations for rationals 2 // 3 // CONSTRUCTION: with (a) no initializer, or (b) an integer 4 // that specifies the numerator, or (c) two integers 5 // specifying numerator and denominator, or 6 // (d) another Rational 7 // 8 // ************************ OPERATIONS********************** 9 // =, +=, -=, /=, *= --> Usual assignment 10 // +, -, /, * --> Usual binary arithmetic11 // <, <=, >, >=, ==,!= --> Usual relational and equality 12 // ++, --, +, -, ! --> Usual prefix, postfix, unary 13 // >> and << --> Input and output 14 // double LongDecimal( ) --> Return double equivalent 15 16 #include <iostream.h> 17 typedef IntType long; 18 19 class Rational 2O { 21 public: 22 // constructors 23 Rational( const IntType & Numerator = 0) : 24 Numer(Numerator), Denom(1) { } 25 Rational( const IntType & Numerator, 26 const IntType & Denominator ) : 27 Numer(Numerator), Denom(Denominator) 28 { FixSigns( ); Reducs( ); } 29 Rational( const Rational & Rhs) : 3O Numer(Rhs.Numer), Denom(Rhs.Denom) { } 31 32 // Destructor33 ~Rational( ) { } Always use constant reference to pass parameter. Without constant, in the function, we may change the parameter by mistake.

  2. 3435 // Assignment Ops 36 const Rational & operator = ( const Rational & Rhs ); 37 const Rational & operator +=( const Rational & Rhs ); 38 const Rational & operator -=( const Rational & Rhs ); 39 const Rational & operator /=( const Rational & Rhs ); 40 const Rational & operator *=( const Rational & Rhs ); 41 42 // Mathematical Binary Ops 43 Rational operator+( const Rational & Rhs ) const; 44 Rational operator-( const Rational & Rhs ) const; 45 Rational operator/( const Rational & Rhs ) const; 46 Rational operator*( const Rational & Rhs ) const; 47 // Relational & Equality Ops 48 int operator< ( const Rational & Rhs ) const; 49 int operator<=( const Rational & Rhs ) const; 50 int operator> ( const Rational & Rhs ) const; 51 int operator>=( const Rational & Rhs ) const; 52 int operator==( const Rational & Rhs ) const; 53 int operator!=( const Rational & Rhs ) const; 54 55 // Unary Operators 56 const Rational & operator++( ); // Prefix57 Rational operator++( int ); // Postfix58 const Rational & operator--( ); // Prefix59 Rational operator --( int ); // Postfix60 const Rational & operator+( ) const;61 Rational operator-( ) const;62 int operator!( ) const; 63 64 // Member function 65 double LongDecimal( ) const // Do the division 66 { return double(Numer) / double (Denom) ; } 67 ie: b=a, b is left hand parameter, which is implied but need to be changed. So you can not add the const key word at the end of the declaration. c=b =a, is the same as c=(b=a). b=a return a constant reference value, which is the reference of b,and act as the right hand parameter of the first =, so and the beginning of the declaration you should add const key word. For example: a=b+c, has three parameter b is implied, c, which is at right hand of +, is Rhs. const means b is a constant parameter, both b and c should not be changed in the function. Ie: j=++ i means i=i+1=> j=i Ie: j=i++ means j=i => i=i+1

  3. 68 // I/O friends: privacy is waived 69 friend ostream & operator<< ( ostream & Out, const Rational & Value ); 71 friend istream & operator>> ( istream & In, Rational & Value ); 73 private: 74 // A rational number is represented by a numerator and 75 // denominator in reduced form 76 IntType Numer; // The numerator77 IntType Denom; // The denominator 78 79 void FixSigns( ); // Ensures Denom >= 0 80 void Reduce( ); // Ensures lowest form 81 } ; 1 void Rational:: FixSigns ( ) { 2 if( Denom < 0 ) {4 Denom = -Denom;5 Numer = -Numer; 6 } 7 } 8 9 void Rational::Reduce ( ) { 10 IntType D = 1;1112 if (Denom != 0 && Numer != 0) D = GCD(Numer, Denom)1415 if( D > 1 ){17 Numer /= D;18 Denom /= D;19 }20 }

  4. 1 Rational // Return a copy of Answer temporary • 2 Rational::operator+( const Rational & Rhs ) const { • 4 Rational Answer( *this ); // Initialize Answer with *this • 5 Answer += Rhs; // Add the second operand, Answer=Answer+Rhs6 return Answer; // Return Answer by copy7 } • 1 int • 2 Rational::operator==( const Rational & Rhs ) const { • 4 return Numer * Rhs.Denom == Denom * Rhs.Numer; • 5 } • 1 const Rational & // Prefix form • 2 Rational::operator++( ){ • 4 Numer += Denom; • 5 return *this; • 6 } • 7 • 8 Rational // Postfix form • 9 Rational::operator++(int) { • 11 Rational Tmp = *this;12 Numer += Denom;13 return Tmp;14 } Dummy only used to indicate postfix form

  5. 1 const Rational & 2 Rational::operator=( const Rational & Rhs ) { 4 if( this != &Rhs ) {6 Numer = Rhs.Numer;7 Denom = Rhs.Denom;8 }9 return *this; 10 } 11 12 const Rational & 13 Rational::operator += (const Rational & Rhs) { 15 Numer = Numer * Rhs.Denom + Rhs.Numer * Denom;16 Denom = Denom * Rhs.Denom;17 Reduce ( );1819 return *this;2O }

  6. 1 int 2 Rational::operator! ( ) const { 4 return !Numer; 5 } 6 7 const Rational & 8 Rational::operator+( ) const { 10 return *this; 11 }12 13 Rational 14 Rational::operator-( ) const { 16 return Rational( -Numer, Denom );17 } 1 istream & 2 operator>>( istream & In, Rational & Value ) {4 In >> Value.Numer;56 char Ch;7 In >> Ch; 8 if( Ch == '/’ ) { 10 In >> Value.Denom;11 Value.FixSigns ( );12 Value.Reduce ( );13 }14 else {16 Value.Denom = 1;17 In.putback(Ch ); 18 } 19 return In;20 } Return the Lhs, for example Cin>>x1>>x2 Cin>>x1 returns the reference of Cin, the second step is Cin>>x2

  7. 23 ostream & • 24 operator<<( ostream & Out, const Rational & Value ) {26 if ( Value. Denom ! = 0 ) {28 Out << Value.Numer;29 if( Value. Denom != 1 ) Out << '/' << Value. Denom;31 return Out;32 }34 // Messy code for Denom == 035 if (Value.Numer == 0 ) Out << "indeterminate";37 else {39 if( Value.Numer < 0 )Out << '-';41 Out << "infinity";42 } • 43 return Out;44 }

  8. Potential Problems with Macros • #define SQ(X) X * X • expands the code SQ(a + b) • to • a+b*a+b • This problem can be avoided by fully parenthesizing the original macro. However, the solution does not protect against improper types being used. This latter defect is remedied by using inline. • Example: • inline int SQ(int x) { return (x * x); } • //Miles are converted to kilometers. • #include <iostream.h> • const float m_to_k = 1.609; • inline int convert (int mi) { return (mi * m_to_k); } • main () { • int miles; • do { • cout << "Input distance in miles: "; • cin >> miles; • cout << "\nDistance is" << convert(miles) << "km.\n"; • } while (miles > 0); • }

  9. Scope Resolution Operator: In addition to identifying members of a class, it can also be used for accessing global variables. Example: // :: scope resolution operator int i = 1; // external i #include <iostream.h> main() { int i = 2; //redeclares i locally { cout << "enter inner block\n"; int n = i; // the global i is still visible int i = 3; //hides the global i // print the local i and the external i cout << i <<" i <> ::i "<< ::i << "\n"; cout << "n = " << n << "\n"; } cout << "enter outer block\n"; cout << i <<" i <> : :i "<< : :i << "\n"; } The output of this code is enter inner block 3 i <> ::i 1 n = 2 enter outer block 2 i <> ::i 1

  10. Prototypes: double sqrt (double x); void make_str (char*, int); void print (const char* s); int printf (char* format, ...); //variable no. of args default values of parameter: int mult(int n, int k = 2) { //k = 2 is default if (k == 2) return (n * n); else return (mult (n, k - 1) * n); } We assume that most of the time the function is used to return the value of n squared. mult(i + 5) //computes (i + 5) * (i + 5) mult(i + 5, 3) //computes (i + 5) cubed Only the trailing parameters of a function can have default values. Aliases: int n;int& nn = n; //nn is an alternative name for n double a[10];double& last = a[9]; //last is an alias for a[9] char& new_line = '\n';

  11. Dynamic Memory Allocation: //Use of new operator to dynamically allocate an array. #include <iostream.h> main() {int* data; int size; cout << "\nEnter array size: "; cin >> size; data = new int[size]; for (int j = 0; j < size; ++j) cout << (data[j] = j) << "\t"; cout << "\n\n"; delete [ ]data; data = new int[size]; for (j = 0; j < size; ++j) cout << data[j] << "\t"; }

  12. Use of Assertions: The practice of thinking out appropriate assertions frequently causes the programmer to avoid bugs and pitfalls. The C and C++ communities increasingly emphasize the use of such assertions. The standard library assert.h provides the macro void assert(int expression); If the expressi on evaluates as false, then execution is aborted with diagnostic output. The assertions are discarded if the macro NDEBUG is defined. Consider a class vect whose constructor is defined as: vect::vect(int n) { if (n <= 1) { cerr << "illegal vect size" << n << endl; exit(l); } size = n; p = new int[size]; } We replace this with vect::vect(int n) { assert (n > 0); size = n; p = new int[size]; assert (p != 0); } //contractual postcondition Assert macro mainly used to debug the program assert(expression) if the expression is true the program continue, otherwise the program stops with an assertion failed error message

More Related