advanced class features: - abstract data type (adt) -object oriented design (ood)

30
This set of notes is adapted from that provided by “Computer Science – A Structured Programming Approach Using C++”, B.A. Forouzan & R.F. Gilberg, Thomson Learning, 2000. Advanced Class Features: -Abstract Data Type (ADT) -Object Oriented Design (OOD) Chapters 11

Upload: kareem-sellers

Post on 02-Jan-2016

23 views

Category:

Documents


2 download

DESCRIPTION

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 ” : - PowerPoint PPT Presentation

TRANSCRIPT

This set of notes is adapted from that provided by “Computer Science – A Structured Programming Approach Using C++”, B.A. Forouzan & R.F. Gilberg, Thomson Learning, 2000.

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

Chapters 11

COMP103 - Adv. Class Features 2

Conventional way of adding 2 fractions

Declare fraction, “fract” as struct type: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 fractionsvoid 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” functionprint(fr1); cout << " + "; print(fr2);cout << " = ";

// calling the “add” functionadd(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

a Value:

Numerator = 1Denominator = 2

b Value:

Numerator = 2Denominator = 3

Class FractPublic functions: Add(), Subtract(),

Multiply(),Divide(), Equal(),LessThan(), Print(), Get()

Private Data members: Numerator,Denominator

Fract a(1,2); Fract b(2,3);

(object 1) (object 2)

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

Implement as C++ Class

Class definition

Class Fract { private:

int numerator;int denominator;

public: Fract();Fract(int n, int d);

Fract(Fract &copyFrom); //Copy Constructorvoid get(); // Read in from cinvoid print(); void increment(void); // Increment by 1 void addTo(Fract &f2);

};

private: user never needsto access this data directly!

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 ConstructorFract::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

class array{

private:

int array_size;

int *array_data;

public:

array(); // default constructor

// copy constructor: value 0bit-wise; 1logical

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 vs. Logical Copy Constructor

size data size data

size data size data

Bitwise (copy s2 to s1)

Logical Copy Constructor

s2s1

s2s1

s1 makes its own“copy” of the data

s1 points to s2’sdata

Case where copy constructor isimportant: Classes that have dynamicmemory

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 isnot 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 a member 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:

. . .

friend Fract addFr(Fract &f1, Fract &f2);

};

Fract addFr(Fract &f1, Fract &f2) // Notice no scope { // operator (::) . . . }

COMP103 - Adv. Class Features 20

Friend FunctionsFriend 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 friendclass 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’ typesswap(a,b); swap(i,j); swap(q,p);

}

COMP103 - Adv. Class Features 23

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!

not overloaded

COMP103 - Adv. Class Features 24

Operator Overloading

Recall:class Fract{

. . .

void increment(void);

void addTo(Fract &fr2);

friend Fract addFr(Fract &f1, Fract &f2);

};

Operation Function Syntax Arithmetic Syntax

Increment:

fr1 = fr1+1

fr1.increment(); ++fr1;

Add to:

fr1 = fr1 + fr2

fr1.addTo(f2); fr1 += fr2;

Add:

fr3 = fr1 + fr2

addFr(f1,f2); f1 + 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 Overloadingclass 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 operatorvoid 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 contructorFract *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);