1 / 30

Advanced Class Features: - Abstract Data Type (ADT) -Object Oriented Design (OOD)

Advanced Class Features: - Abstract Data Type (ADT) -Object Oriented Design (OOD). Chapters 11. Conventional way of adding 2 fractions. Declare fraction, “ fract ” as struct type: struct Fract { int numerator; int denominator; }; Define functions “ add ” and “ print ” :

Download Presentation

Advanced Class Features: - Abstract Data Type (ADT) -Object Oriented Design (OOD)

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. Advanced Class Features:-Abstract Data Type (ADT) -Object Oriented Design (OOD) Chapters 11

  2. Conventional way of adding 2 fractions • Declare fraction, “fract”as structtype: • struct Fract • { • int numerator; • int denominator; • }; • Define functions “add”and “print”: • void add(Fract &f1, Fract f2) • { • f1.numerator = f1.numerator*f2.denominator + • f2.numerator*f1.denominator; • f1.denominator = f1.denominator*f2.denominator; • return; • } // add: f1 = f1 + f2; • void print (Fract f) • { • cout << f.numerator << "/" << f.denominator; • } COMP103 - Adv. Class Features

  3. Conventional way of adding 2 fractions void main(){ // Local Declarations - conventional Fract fr1, fr2; // Assigning values to fr1 and fr2 fr1.numerator = 1; fr1.denominator = 3; fr2.numerator = 2; fr2.denominator = 5; cout << "Fract: "; // calling the “print” function print(fr1); cout << " + "; print(fr2); cout << " = "; // calling the “add” function add(fr1, fr2); print(fr1); cout << "\n"; } COMP103 - Adv. Class Features

  4. Conventional way of adding 2 fractions Note: users need to know • the field names, i.e., fr1.numerator and fr1.denominator • how to initialize the fractions, e.g. fr1.numerator=1; • where put the target fraction fr1 as the first parameter in add(fr1, fr2) • that the first parameter should be passed by reference,i.e.,void add(Fract &f1, Fract f2) These are implementation details of Fraction. One should not bother the users with these details. Users should only be concerned of what a “Fraction object” can do but not how it accomplishes its task.  Use Abstract Data Type also referred to as Object Oriented Design COMP103 - Adv. Class Features

  5. Using “ADT” (or “OOD”) • The main program becomes: • void main() { • // Local Declaration using ADT (class type) • // assign values - constructors • Fract f1(1,3), f2(2, 5); • cout << "Fraction: "; • // class member function “print” • f1.print(); • cout << " + "; • f2.print(); • cout << " = "; • // class member function “add” • f1.add(f2); • f1.print(); • cout << "\n"; • } COMP103 - Adv. Class Features

  6. Abstract Data Type (ADT) When we implement an “object” as an ADT (Abstract Data Type), • We hide the implementation details from the users • This is facilitated by using CLASS type in C++ • Data fields should be declared as private • What the object can do is provided as public functions (methods) COMP103 - Adv. Class Features

  7. Object Oriented Design Class Fract Publicfunctions: Add(), Subtract(), Multiply(),Divide(), Equal(), LessThan(), Print(), Get() PrivateData members:Numerator, Denominator (object 1) (object 2) Fract a(1,2); Fract b(2,3); aValue: bValue: Numerator = 1 Numerator = 2 Denominator = 2 Denominator = 3 COMP103 - Adv. Class Features

  8. Case Study: “Fract” Class • Design a simple abstract data type (ADT): Fract • Data (private): numerator, denominator • Operations (things you can do with fractions) • initialize [ Constructors ] • read • print • copy • increment fraction (add +1) • add to another fraction // f1 = f1 + f2 • add two fractions // f3 = f1 + f2 COMP103 - Adv. Class Features

  9. private: user never needs to access this data directly! Implement as C++ Class Class definition Class Fract { private: int numerator; int denominator; public: Fract(); Fract(int n, int d); Fract(Fract &copyFrom); //Copy Constructor void get(); // Read in from cin void print(); void increment(void); // Increment by 1 void addTo(Fract &f2); }; COMP103 - Adv. Class Features

  10. Constructors (3 Types) // Default Constructor: Fract=1/1; Fract::Fract() { numerator = 1; denominator = 1; } // Explicit value Constructor: Fract=n/d; Fract::Fract(int n, int d) { numerator = n; denominator = d; } // Bit-wise Copy Constructor Fract::Fract(Fract &copyFrom) { numerator = copyFrom.numerator; denominator = copyFrom.denominator; } COMP103 - Adv. Class Features

  11. Copy Constructor • Copy Constructor is a special constructor • It is called in the following situation • Fract fr2(fr1); // fr2 = fr1; • Copy Constructor Syntax • ClassName::ClassName(ClassName &var) • Examples: • MyString::MyString(MyString &s) • Fract::Fract(Fract &f) • Complex::Complex(Complex &c) • array::array(array &A) // recall: Constructors.cpp COMP103 - Adv. Class Features

  12. Bitwise vs. Logical Copy Constructor Case where copy constructor is important: Classes that have dynamic memory class array{ private: int array_size; int *array_data; public: array(); // default constructor // copy constructor: value 0bit-wise; 1logical array(array &A, int value); . . . }; // Constructors.cpp (24 March Notes) Array::array(array &A, int value){ array_size = A.size(); switch(value) { case 0:// Bitwise Copy array_data = A.array_data; break; case 1: // Logical Copy array_data = new int[array_size]; for (int i=0; i < array_size; i++) array_data[i] = A.array_data[i]; break; } } Bitwise (copy s2 to s1) s1 s2 size data size data s1 points to s2’s data Logical Copy Constructor s1 s2 size data size data s1 makes its own “copy” of the data COMP103 - Adv. Class Features

  13. Functions: “get” and “print” void Fract::get() { cout << “ Input Fraction (n d): “; cin >> numerator >> denominator; } void Fract::print() { if (denominator == 0) // n/0 is infinity cout << “Infinity\”; else cout << numerator << “/” << denominator; } COMP103 - Adv. Class Features

  14. Functions: “increment” and “addTo(. . .)” // increment: f1 = f1 + 1  a/b + 1 = (a+b)/b void Fract::increment() // Add one to fraction { numerator += denominator; } // addTo: f1 = f1 + f2  a/b + c/d = (a*d + c*b)/b*d void Fract::addTo(Fraction &f2) { numerator = numerator*f2.denominator + f2.numerator*denominator; denominator = denominator*f2.denominator; } COMP103 - Adv. Class Features

  15. We want:f3 = f2 + f1 (how?) void main() { // declare and initialize f1 and f2 Fract f1(1,2), f2(1,2); // copy f1 to f3 Fract f3(f1); // add f2 to f3,i.e.,f3 = f3 + f2 f3.addTo(f2); } This addTo(...) method is not very intuitive. . not easy to use . . COMP103 - Adv. Class Features

  16. Another function: addFr(. . .) Class Fract { private: int numerator; int denominator; public: Fract(); Fract(int n, int d); Fract(Fract &copyFrom); //Copy Constructor void get(); // Read in from cin void print(); void increment(); // f1 = f1 + 1; void addTo(Fract &f2); // f1 = f1 + f2; Fract addFr(Fract &f1, Fract &f2); }; COMP103 - Adv. Class Features

  17. Member Function addFr(. . .) • Remember we want f3 = f2 + f1 • addFr(. . .), as amember function of class Fract, must be called by an object! void main() { // declare and initialize f1 and f2 Fract f1(1,2), f2(1,2), f3; // member function can only be called by an object f3 = f1.addFr(f1,f2); } • Note, we can also achieve the same result by: f3 = f2.addFr(f1,f2); or f3 = f3.addFr(f1,f2); Awkward usage!! We want f3 = f1 + f2! COMP103 - Adv. Class Features

  18. Solution: addFr(. . .) as an external function Fract addFr(Fract &f1, const Fract &f2) { Fract tempFr; tempFr.numerator = f1.numerator*f2.denominator + f2.numerator*f1.denominator; tempFr.denominator = f1.denominator*f2.denominator; return (tempFr); } Void main() { Fract f1(1,2), f2(1,2), f3; f3 = addFr(f1,f2); } • This is what we want • - But, addFr() cannot access Fract’s private data! • We could make Fract’s data public - This violates ADT design - Allows user unnecessary access COMP103 - Adv. Class Features

  19. Another Solution: Friend Functions C++ has a way to allow non-member function to access private variables: friend functions class Fract { private: . . . public: . . . friendFract addFr(Fract &f1, Fract &f2); }; Fract addFr(Fract &f1, Fract &f2)// Notice no scope {// operator (::) . . . } COMP103 - Adv. Class Features

  20. Friend Functions Friend Functions • Are not members of a class • They are associated with the class and given special privileges • Allow to access private members data and functions • To declare an external function as a friend function: prefix its prototype with the keyword friend class MyClass{ . . . friend void doSomething1(MyClass c1, . . . ); friend int doSomething2(Myclass c1, . . . ); friend MyClass doSomething3(. . .); friend OtherClass; // A friend can actually be another class! // (We’ll re-visit this with linked-list) }; COMP103 - Adv. Class Features

  21. Overloading • Overloading - Definition of two or more functions or operators with the same identifier (name) • C++ allows two types of overloading: • Function Overloading • Operator Overloading COMP103 - Adv. Class Features

  22. C++ Function Overloading Example: “swap” void swap(char &, char &); void swap(int &, int &); void swap(float &, float &); void main() { char a=‘x’, b=‘y’; int i=10 , j=-10; float q=1.34, p=3.14; // compiler knows which one to call // by examining the parameters’ types swap(a,b); swap(i,j); swap(q,p); } COMP103 - Adv. Class Features

  23. not overloaded Function Overloading • Compiler uses only the parameters (not the return type) to detect overloading float *average(int *array); int *average (int *array); These will not be considered overloaded and will cause a compiler error! COMP103 - Adv. Class Features

  24. Operator Overloading • Recall: class Fract{ . . . void increment(void); void addTo(Fract &fr2); friend Fract addFr(Fract &f1, Fract &f2); }; COMP103 - Adv. Class Features

  25. Operator Overloading • C++ allows us to overload the operators for a more natural coding style class Fract{ private: int numerator; int denominator; public: . . . void operator++(); // increment: ++fr1 } void Fract::operator++(){ numerator += denominator;} COMP103 - Adv. Class Features

  26. Operator Overloading class Fract{ private: int numerator; int denominator; public: . . . void operator++(); void operator+=(Fract &fr2); friend Fract operator+(Fract &f1, Fract &f2 ); } void Fract::operator++(){// same as increment– fr1 = fr1 + 1 } void Fract::opeartor+=(Fract &fr2){// same as addTo– fr1 = fr1 + fr2 }Fract operator+(Fract &fr1, Fract &fr2){// same as addFr – fr3 = fr1 + fr2 } COMP103 - Adv. Class Features

  27. Overloading the Copy operator “ = “ • Can write your own logical copy operator (Same as copy constructor) class array { . . . void operator=(array &A); }; // Logical Copy operator void array::operator=(array &A) { . . . // (see slide 12) } void main(){ Array A1, A2; . . . A2 = A1; // performs the logical copy!! } COMP103 - Adv. Class Features

  28. Dynamic memory and classes • You can dynamically allocate a class object • Use a pointer to a class (p.564), e.g. // default-constructorFract *pf1 = new Fract; // explicit-value contructor Fract *pf2 = new Fract(1,2); • Use member operator (.) (*pf1).get(); (*pf1).print(); • Or use selection operator (->) pf1->get(); pf1->print(); COMP103 - Adv. Class Features

  29. Deletion of Dynamic Objects • Deletion and destructors • Recall the special destructor function: ~<ClassName>() • The “delete” keyword used to free dynamic memory will call the destructor of an object Fract *pf1 = new Fract(1,2); pf1->print(); // or (*pf1).print(); delete pf1;// pf1’s destructor will be called COMP103 - Adv. Class Features

  30. Summary • More C++ and C++ Class Functionality • Fract Case Study • Copy Constructor • Bitwise vs. Logical Copy • Friend Functions • Function Overloading • Operator Overloading • Dynamically Allocated Objects, Pointers to Objects • Fract *pf = new Fract(1,2); COMP103 - Adv. Class Features

More Related