33
1 Computation Computation 5JJ70 5JJ70 Implementatie Implementatie van van rekenprocessen rekenprocessen Object Oriented Object Oriented Programming Programming Henk Henk Corporaal Corporaal February 2011 February 2011

Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

1

ComputationComputation

5JJ70 5JJ70 ‘‘ImplementatieImplementatie van van rekenprocessenrekenprocessen’’

Object Oriented Object Oriented ProgrammingProgramming

HenkHenk CorporaalCorporaalFebruary 2011February 2011

Page 2: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 2

Welcome!

• Previous lecture:– Structures– C++ class: introduction

• Today:– Hashing hints (other hash function)– Structures and Classes recap– Continue our adventures in the aquarium– Multiple constructors– Introduction to Class Inheritance

• Book: The C++ Programming LanguageBjarne Stroustrup

• Related Labs– Hash assignment, task 7– task 8 on linked lists uses C++ / OOProgramming

Page 3: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 3

Finding strings• Suppose we have a set of n strings in an array.• To check whether a string is in the set, we can perform ‘brute-force’comparison:

int string_exists(char * string, char ** string_array)

{

int j;

for(j = 0; string_array[j] != 0; j++) {

if(strcmp(string_array[j], string) == 0)

return 1; // bingo! found string

}

return 0; // string not found

}

Here I assume that thearray is terminatedby a Null pointer.

0

string

string-array

p i e t 0

s i n t 0

a a i i i i 0

a i 0

a a a a i i i 0

j

stackframe ofstring_exists

Page 4: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 4

Finding strings

• If the string exists, this will take me on average n/2 string comparisons. If it doesn’t, this will set me back n string comparisons.

• This algorithm is O(n) (i.e. run time is in the order of n)– The more strings there are, the slower it will get.

• This is often unacceptably slow.

int string_exists(char * string, char ** string_array)

{

int j;

for(j = 0; string_array[j] != 0; j++) {

if(strcmp(string_array[j], string) == 0)

return 1; // bingo! found string

}

return 0; // string not found

}

Page 5: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 5

Hashing: searching a subset

• Lets divide the strings into m subsets. In that case, the string lookup will take at most n/m steps. If m is sufficiently large, the order of the algorithm becomes O(1), that is, constant complexity!!

• But… This will only work if we know which of the m subsets of strings we need to check.

• So lets invent a function int hashhash(char * string) that returns a (homogenously distributed) number for each string. This numberindexes the subset of strings we want to search.

int string_exists(char * string, char *** string_array)

{

int j;

int hashval = hash(string);

for(j = 0; string_array[hashval][j] != 0; j++) {

if(strcmp(string_array[hashval][j], string) == 0)

return 1; // bingo! found string

}

return 0; // string not found

}

We only search the subset ofstrings that belong to the hashval

Page 6: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 6

Hash implementation: 3 dim. array

B

A

L

K

I

E

!

!

\0

..

char *

char

.. .. .. .. .. .. 0..

..

..

..

..

..

..

..

char **

.. char ***

char ** hashtable[HASHSIZE];

char *** a = hashtable

char ** b = hashtable[1]

char * c = hashtable[1][5]

char d = hashtable[1][5][2]

Page 7: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 7

A possible hash function

#define HASHSIZE 100

unsigned int hash(char * str)

{

unsigned int hashval;

for(hashval = 0; *str != '\0'; str++) { // steps through string

hashval = *str + 31 * hashval; // mangles string

}

return hashval % HASHSIZE;

}

Taking the remainder ensures that the returnedvalue is between 0 and HASHSIZE-1

Here the ascii value of the characteris multiplied by (31 * the previoushash value). 31 is a ‘magic number’that was determined experimentally.

hash(”a”) hashval = 97 -> returns 97

hash(“aa”) hashval = 97 + (31 * 97) = 3104 -> returns 4

hash(“aaa”) hashval = 97 + (31 * 3104) = 96321 -> returns 21

hash(“aaab”) = ( 98 + (31 * 96321) )%100 = 49 -> return 49

Page 8: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 8

Another hash function

• This one is similar, except that the mangling happens using exors and shifts

#define HASHSIZE 100

unsigned int hash(char * str)

{

unsigned int hashval;

for(hashval = 0; *str != '\0'; str++) {

hashval = (hashval<<4)^(hashval>>28)^(*str);

}

return hashval % HASHSIZE;

}

^ exor operatorfor all 32 pairs of input bits do:

0^0 = 00^1 = 11^0 = 11^1 = 0

Page 9: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 9

A suggestion for P7 program structurechar **hashtable[HASHSIZE]; // global database

void main(void)

{

char command[100], char sentence[1000];

while(1) { // endless command loop

scanf(“ %s”, command);

if(strcmp(command, “stop”) == 0)

break;

if(strcmp(command, “test”) == 0) {

random_sentence(sentence);

printf(“%s\n”, sentence);

continue;

}

if(strcmp(command, “add”) == 0) {

read_sentence(sentence);

add_sentence_to_hashtable(sentence);

continue;

}

// etc.

}

}

void random_sentence(char * buffer) { .. }

void read_sentence(char * buffer) { .. }

Note: your hashtable may be slightly different

Page 10: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 10

Recap: Structures

• A structure defines a data type that consists of one or more members.• Examples:

struct coordinate {

int x;

int y;

};

struct coordinate a, b[3];

struct taxpayer {

char name[80];

int sofi_no;

double balance;

};

struct taxpayer pietje;

sofi_no

balance

pietje

name

a x

y

x

y

x

y

x

y

b

b[1].y

pietje.name

pietje.name[79]

Page 11: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 11

Example

struct coordinate crd; /* a struct variable called crd */

struct taxpayer cor; /* a taxpayer called cor */

struct coordinate * crd_p = &crd; /* pointer to a coordinate structure */

struct taxpayer * taxp = &cor; /* pointer to a pointer to a taxpayer */

struct taxpayer family[4]; /* an array of 4 taxpayers */

crd.x = 3; crd.y = 5; /* set values of x and y in crd */

crd.x++; /* increment crd.x to 4 */

crd_p->x = 10; crd_p->y = 20; /* set the values of x and y in crd */

++crd_p->y; /* increment crd_p->y (=crd.y) to 21 */

strcpy(cor.name,”Cor ‘de boon’ Boonstra”); cor.sofi_no = 74365235;

cor.name[8] = ‘B’; /* set the 9th index of cor.name */

taxp->balance = -654643.00;

family[2].balance = 40.0; family[2].balance += 100.0;

printf(“Taxpayer %s Sofi number: %d, balance %.2f\n”,

cor.name, taxp->sofi_no, cor.balance);

• In case of a struct, use the dot .– struct_var.fname

• In case of a pointer to a struct, we use the arrow ->– struct_var->fname

struct coordinate {

int x;

int y;

};

struct taxpayer {

char name[80];

int sofi_no;

double balance;

};

Page 12: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 12

Self referential structs

struct Node {

int data;

struct Node * nextptr;

};

struct Node a, b;

/* or use

typedef struct Node mynode;

mynode a, b;

*/

a.data = 34; b.data = 35;

a.nextptr = &b;

b.nextptr = 0;

a

b

34

35

0

Page 13: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 13

More onTypedef

typedef int aaa, bbb, ccc;

typedef int ar[15], arr[9][6];

typedef char c, *cp, carr[100];

/* now declare some objects */

aaa int1; /* all ints */

bbb int2;

ccc int3;

ar yyy; /* array of 15 ints */

arr xxx; /* 9*6 array of int */

c ch; /* a char */

cp pnt; /* pointer to char */

carr chry; /* array of 100 char */

typedef int (*a10ptoa5i[10])[5]; // oeps !!

/* or

typedef int a5i[5];

typedef a5i *a10ptoa5i[10]; */

Page 14: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 14

Struct vs. Class

typedef struct {

char * _name; /* name of fish */

int _weight; /* its weight */

} fish;

void main() {

fish * f1, * f2;

/* make a fish called orca */

f1 = (fish *) malloc(sizeof(fish));

f1->_name = (char *) malloc(5);

strcpy(f1->_name,”Orca”);

f1->_weight = 250;

/* make a fish called seal */

f2 = (fish *) malloc(sizeof(fish));

f2->_name = (char *) malloc(5);

strcpy(f2->_name,”Seal”);

f2->_weight = 15;

/* orca eats seal */

f1->_weight += f2->_weight;

free(f2->_name);

free(f2);

printf(“Orca weighs %d kg\n”,

f1->_weight);

}

class fish {

public:

fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

}

~fish() { delete _name; }

void eat(fish * victim) {

_weight += victim->weight();

delete victim;

}

int weight(void) { return _weight; }

private:

char * _name; // name of fish

int _weight; // its weight

};

void main(void) {

fish * f1 = new fish(“Orca”, 250);

fish * f2 = new fish(“Seal”, 15);

f1->eat(f2);

printf(“Orca weighs %d kg\n”,

f1->weight());

}

Page 15: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 15

The C++ class in detail

class fish {

public:

fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

}

~fish() { delete _name; }

void eat(fish * victim) {

_weight += victim->weight();

delete victim;

}

int weight(void) { return _weight; }

private:

char * _name; // data member

int _weight; // data member

};

void main(void) {

fish * f1 = new fish(“Orca”, 250);

fish * f2 = new fish(“Seal”, 15);

f1->eat(f2);

printf(“Orca weighs %d kg\n”,

f1->weight());

}

• The class definition describes the object.

• It contains member functions and data members.

• The fish object is 8 bytes big, just like the fish struct.

• Notice that the actual main() is much smaller, because functionality was moved to the member functions of the object.

Page 16: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 16

The C++ class: privacy

class fish {

public:

fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

}

~fish() { delete _name; }

void eat(fish * victim) {

_weight += victim->weight();

delete victim;

}

int weight(void) { return _weight; }

private:

char * _name;

int _weight;

};

void main(void) {

fish * f1 = new fish(“Orca”, 250);

fish * f2 = new fish(“Seal”, 15);

f1->eat(f2);

printf(“Orca weighs %d kg\n”,

f1->weight());

}

public:

The following functionsand data are accessible by‘everyone’.

private:

The following functionsand data are accessible onlyby the member functionsof this class.

The actual data membersof the object. This is just like in the struct. They determine the memory footprint. They are private: they cannot be changedby ‘foreign’ functions.

As a convention, we putan underscore in front of the data members of the class.

Page 17: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 17

The C++ class: member functions

class fish {

public:

fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

}

~fish() { delete _name; }

void eat(fish * victim) {

_weight += victim->weight();

delete victim;

}

int weight(void) const

{ return _weight; }

private:

char * _name;

int _weight;

};

void main(void) {

fish * f1 = new fish(“Orca”, 250);

fish * f2 = new fish(“Seal”, 15);

f1->eat(f2);

printf(“Orca weighs %d kg\n”,

f1->weight());

}

A member function to provide(read only) access to the data member_weight. The statements are betweenthe accolades.

Gives a compile error, becausewe cannot access the private dataof the fish.

printf(“Orca weighs %d kg\n”,

f1->_weight);

const means that calling this memberfunction will not change the objectin any way.

• Member functions are just like normal routines. They have defined the class data members as local variables.

• Member functions can be public or private.

Page 18: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 18

Prototype and body of member functionsclass fish {

public:

fish(char * name, int weight);

~fish();

void eat(fish * victim);

int weight(void);

private:

char * _name;

int _weight;

};

// function bodies

fish::fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

}

fish::~fish() { delete _name; }

void fish::eat(fish * victim) {

_weight += victim->weight();

delete victim;

}

int fish::weight(void) {

return _weight;

}

Prototype of eat()member function.

• The body of a member function can be put at a different spot, outside of the class.

• In fact, this is what we do most.

Body of eat() member function.The type and argument match with the prototype in the class.

Using fish:: we specify the class this function is in.

Page 19: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 19

Construction: making an object

class fish {

public:

fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

}

~fish() { delete _name; }

void eat(fish * victim) {

_weight += victim->weight();

delete victim;

}

int weight(void) { return _weight; }

private:

char * _name;

int _weight;

};

void main(void) {

fish * f1 = new fish(“Orca”, 250);

fish * f2 = new fish(“Seal”, 15);

f1->eat(f2);

printf(“Orca weighs %d kg\n”,

f1->weight());

}

A member function that has the same name as the class is a constructor.It will be called when we create a new object. Here we definethe actions that we take whenthe object is born.

The C++ function new allocates memory for the object, and then calls the constructor member function.Think of it as a fancy version of malloc()

This mallocs the space forthe internal name string.

• C++ provides commands new and delete .

Page 20: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 20

Multiple constructorsclass fish {

public:

fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

}

fish(char * name) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = 0;

}

fish(int weight) {

_weight = weight; _name = 0;

}

//…

private:

char * _name;

int _weight;

};

void main(void) {

fish * f1 = new fish(“Orca”, 250);

fish * f2 = new fish(“Seal”);

fish * f3 = new fish(20.0);

//…

}

First ctor of fish has 2 arguments.

Second ctor has only 1.

• The linker will pick the constructor, depending on the best ‘match’.

• Sometimes this is ambiguous.

Ctor 1.

Ctor 2

Third ctor has one as well,but the argument is ofanother type.

Ctor 3 (probably)(double converted to int)

Page 21: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 21

Destruction of an object

class fish {

public:

fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

}

~fish() { delete _name; }

void eat(fish * victim) {

_weight += victim->weight();

delete victim;

}

int weight(void) { return _weight; }

private:

char * _name;

int _weight;

};

void main(void) {

fish * f1 = new fish(“Orca”, 250);

fish * f2 = new fish(“Seal”, 15);

f1->eat(f2);

printf(“Orca weighs %d kg\n”,

f1->weight());

}

In this case, we need to delete (return to the memory manager) thestring that is allocated as part ofthis object. In this way, the life anddeath of the child object is directly tied to the parent.

A ~ before member function that has the same name as the class is the destructor.It will be called automatically when deleting an object. The actionsdefined here are executed justbefore the memory of the objectis released.

Notice that eating another fishimplies killing the victim. This willcall the destructor on the victim object.

Page 22: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 22

Object Oriented programming in C++ • Objects are described in a ‘class’. • A class is just a collection of several data members in memory, similar to a C-style structure

• Classes have methods that operate on them– These are just functions– The pointer called 'thisthis''points to the current object

• 2 important events are covered through member functions:– Birth: constructor with actions that initialize the class

– Death: destructor actions that clean up the class

• Add arbitrary member functions

class person {

public:

person(char * name) {

this->_name =

new char[strlen(name)+1];

strcpy(this->_name, name);

}

~person() {

delete this->_name;

}

void print() {

printf(“My name is %s\n”,

this->_name);

}

const char * getname(void) const {

return this->_name;

}

private:

char * _name; // data member

};

Page 23: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 23

Trouble in the aquarium

my_aquarium

goldfish

guppy

Quiz:

What will

be printed?

watertor

Crash!

void main(void) {

aquarium my_aquarium;

fish * f1, *f2;

my_aquarium.add((f1 = new fish(“Guppy”,1)));

my_aquarium.add((f2 = new fish(“Goldfish”,2)));

fish * predator =

new fish(“Geelgerande Watertor”, 6);

my_aquarium.add(predator);

predator->eat(f1); predator->eat(f2);

my_aquarium.print();

}

In C++ we may declare variables anywhere! In C theymust be declared beforethe first statement

Page 24: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 24

What went wrong?class aquarium {

public:

aquarium() { _fish_count = 0; } // constructor

~aquarium() { // destructor

while(_fish_count > 0) // all fish die!

delete _fishes[--_fish_count];

}

void add(fish * new_fish) {

_fishes[_fish_count++] = new_fish;

}

void print(void) {

printf(“Contents of aquarium:\n”);

for(int j = 0; j < _fish_count; j++)

_fishes[j]->print();

}

private:

fish * _fishes[MAXFISHES]; // ptrs to contents

int _fish_count; // # of fish in tank

};

_fish_count = 3

_fishes[]:

aquarium

Guppy

fish

Goldfish

fish

Geelgerande

watertor

fish

• The class aquarium didn’t notice that 2 of the fish were eaten.

• When the print() function was called, a ‘dead’pointer was used.

Page 25: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 25

A fix: make fish remember aquarium

class fish {

public:

fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

_aquarium = 0; // not in aquarium

}

~fish() {

if(_aquarium)

_aquarium->remove(this);

delete _name;

}

// …

aquarium * _aquarium; // NEW!

private:

char * _name;

int _weight;

};

In the destructor of fish we removeit from its aquarium as well. If thefish dies for whatever reason, thisfunction is called.this is an implicit pointer to the current class object

• If a fish dies, then it must be removed from an aquarium it is in…

• Idea: maintain a pointer to the aquarium in each fish.

New data member: A pointer to the aquarium the fish lives in.

During construction, each datamember field is initialized.Initializing the pointer _aquarium to 0 means its not inan aquarium.

Page 26: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 26

Aquarium in action

_fish_count:

_fishes[]:

big aquarium

aquarium big_aquarium;

fish * f1, * f2;

big_aquarium.add((f1 = new fish(“Guppy”,1)));

big_aquarium.add((f2 = new fish(“Goldfish”,2)));

fish * predator = new fish(“Geelgerande Watertor”, 6);

big_aquarium.add(predator);

predator->eat(f1); // predator eats guppy

delete predator; // and we kill the predator

aquarium small_aquarium;

small_aquarium.add(f2); // move fish to it

_fish_count: 0

_fishes[]:

small aquarium_aquarium

_name: Guppy

_weigth: 1

_aquarium

_name: Goldfish

_weigth: 2

_aquarium

_name: Watertor

_weigth: 6

fish

01232101

7

f1

f2

predator

Page 27: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 27

Building relations between objectsclass aquarium {

public:

aquarium() { _fish_count = 0; }

~aquarium() {

while(_fish_count > 0)

delete _fishes[0];

}

void add(fish * new_fish) {

if(new_fish->_aquarium != 0)

new_fish->_aquarium->remove(new_fish);

this->_fishes[_fish_count++] = new_fish;

new_fish->_aquarium = this;

}

void remove(fish * old_fish) {

for(int j = 0; j < _fish_count; j++)

if(_fishes[j] == old_fish) {

for( ; j < _fish_count-1; j++)

_fishes[j] = _fishes[j+1];

_fish_count--;

return;

}

}

}

//…

private:

fish * _fishes[MAXFISHES];

int _fish_count;

};

class fish {

public:

fish(char * name, int weight) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

_weight = weight;

_aquarium = 0; // no aquarium yet

}

~fish() {

if(_aquarium)

_aquarium->remove(this);

delete _name;

}

// …

aquarium * _aquarium; // I am in

private:

char * _name;

int _weight;

};

The delete offish will decrease _fish_count

We have to find thefish in the array, toget rid of it.

When a fish is added to the aquarium, we set the _aquarium pointer of thatfish.In case a fish is already in another Aquarium, it is removed from that

In C++ a variablecan be declared here!

Page 28: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 28

So now it works just fine

void main(void) {

aquarium big_aquarium;

fish * f1, * f2;

big_aquarium.add((f1 = new fish(“Guppy”,1)));

big_aquarium.add((f2 = new fish(“Goldfish”,2)));

fish * predator =

new fish(“Geelgerande Watertor”, 6);

big_aquarium.add(predator);

predator->eat(f1); // predator eats guppy

delete predator; // and we kill the predator

big_aquarium.print();

aquarium small_aquarium; // make another aquarium

small_aquarium.add(f2); // move fish to it

small_aquarium.print();

}

1 Objects in the aquarium:

Fish: Goldfish, weight:1

Notice that there were 2 different causes of death, but that the big_aquarium was kept up-to-date automatically.

1 Objects in the aquarium:

Fish: Goldfish, weight:1

Goldfish is removed frombig_aquarium first.

Page 29: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 29

Inheritance of properties

• The aquarium may contain various kinds of living creatures:– plants– orca’s– seals, guppies, etc.

• These objects have some things in common, some not:– They all live in the aquarium– They all have a weight– All animals have names– Predators eat other animals.- etc.

• If the aquarium breaks, all creatures will die.

living_creature-weight

-aquarium

plantanimal-name

goldfish

Carnivorekill(animal)

orca seal

Herbivoreeat(plant)

guppyshark

Possible inheritance hierarchy

Page 30: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 30

The base class for living creatures

// base class

class living_creature {

public:

living_creature();

~living_creature();

void print(void);

aquarium * _aquarium;

private:

int _weight;

};

class aquarium {

public:

aquarium() { _creature_count = 0; }

~aquarium() { // kill all creatures

while(_creature_count > 0)

delete _creatures[0];

}

void add(living_creature * creature) {

_creature[_creature_count++] = creature;

// more code to add creature

}

void remove(living_creature * creature) {

// code to remove creature

}

void print(void) {

printf(“Contents of aquarium:\n”);

for(int j = 0; j < _creature_count; j++)

_creatures[j]->print();

}

private:

living_creature * _creatures[MAXCREATURES];

int _creature_count;

};

• We build the aquarium such that it contains objects of the type living_creature.

• living_creature is used as a based class for all living things.

Note: The bodies of these functions are elsewhere !!

Aquarium can contain any typeof living creature.

Page 31: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 31

Inheritance

living_creature-weight

-aquarium

plantanimal-name

goldfish

predatorkill(animal)

orca seal

fish

guppyshark

class living_creature {

public:

living_creature(void);

~living_creature();

void print(void);

aquarium * _aquarium;

private:

int _weight;

};

class animal : public living_creature {

public:

animal(char * name) {

_name = new char[strlen(name)+1];

strcpy(_name, name);

}

~animal() {

delete _name;

}

// …

private:

char * _name;

};

class predator : public animal {

public:

kill(animal * victim) {

delete victim; // munch!

}

// …

};

class fish : public animal {

// …

};

An animal has a name, andall properties of the livingcreature.

A predator can kill otheranimals. Otherwise it is thesame as an animal.

A fish has all propertiesof an animal.

Page 32: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 32

So now we may use this as follows

void main(void) {

aquarium my_aquarium;

living_creature *c1, *c2, *c3, *c4, *c5;

my_aquarium.add((c1 = new plant() ));

my_aquarium.add((c2 = new fish(“Guppy”) ));

my_aquarium.add((c3 = new fish(“Goldfish”) ));

my_aquarium.add((c4 = new predator(“Shark”) ));

my_aquarium.add((c5 = new animal(“Diver”) ));

// shark eats human

(predator *)c4->eat((animal *) c5);

my_aquarium.print();

} 4 Objects in the aquarium:

Plant: weight:0

Fish: Guppy, weight:0

Fish: Goldfish, weight:0

Predator: Shark, weight:0

We’re using pointers to living creatures.

c4 is of type living_creature. Thattype does not have the member function eat().Since c4 is actually apredator, we can up-castit to type predator. That will provide accessto the member function.

Add a plant

Make guppy, toss it inthe aquarium

For simplicity, the weight was not used. The base classhas initialized it to 0.

Page 33: Object Oriented Programming · strcpy(cor .name,”Cor ‘de boon’ Boonstra”); cor .sofi_no = 74365235; cor .name[8] = ‘B’; /* set the 9th index of cor.name */ taxp ->balance

© PG/HC Programming 5JJ70 pg 33

Summary

• Classes are a C++ type, encapsulating data and data-access functions (member functions).

• Classes have a public and a private area.• Two member functions are special: constructor and destructor• A class can have multiple constructor functions => function overloading:– The compiler selects the appropriate constructor based on the argument list

• The implementation of Member functions can be defined inside ouroutside a class– In the latter case we define a prototype inside the class and use the classname::f(){..} notation to give the implementation

• Class functionality can be inherited by other classes– The inherited class is called the base class, the inheriting class the derived class