object oriented programming elhanan borenstein [email protected] lecture #8 copyrights © elhanan...

28
Object Oriented Programming Elhanan Borenstein [email protected] Lecture #8 copyrights © Elhanan Borenstein

Upload: bernard-hodge

Post on 18-Dec-2015

220 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Object OrientedProgramming

Elhanan Borenstein

[email protected]

Lecture #8

copyrights © Elhanan Borenstein

Page 2: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Agenda Inheritance & Polymorphism – A short reminder

File Handling in C++ Polymorphism & Files: Serialization

copyrights © Elhanan Borenstein

Page 3: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Inheritance & Polymorphisma Short Reminder

copyrights © Elhanan Borenstein

Page 4: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

InheritanceExample

class Base1 {

int var1; public:

Base1() {…} // constructorvoid OldFunc() {…}void Init() {…}

};

class Derived1 : [public|protected|private] Base1{

int var2; public:

Derived1() {…} // constructorvoid Init() {…} // overridevoid Do(){…}

};copyrights © Elhanan Borenstein

Page 5: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Inheritance

When inheriting a class, we inherit all its members and they will be included in the derived class:

Somewhat similar to object data members (embedded):

To differentiate, we can check the logics behind the implemented entities: Inheritance: The derived class is a type of the base class.

Inner class: The inner class is a part of the external class.

The Logic behind Inheritance

Base (father)

AdditionsDerived (son) (SIZE?)

Additions

embeddingclass

inner object

copyrights © Elhanan Borenstein

Page 6: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

InheritanceUnderstanding Inheritance - Example

class GraphicItem {

int color; public:

GraphicItem() {…} // constructorvoid Draw() {…}void ChangeColor(int n_clr) {…}

};

class CPoint : public GraphicItem{

int m_x, m_y; public:

CPoint() {…} // constructorvoid Draw() {…} // overridevoid Align(){…}

};

GraphicItem G, *pG;CPoint P, *pP;…

G = P;

P = G;

pG = pP;

pP = pG;

copyrights © Elhanan Borenstein

Page 7: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Inheritance

All the data members of the base class also exists in the derived class. But there are cases where we cannot access these members. Hiding (but we can still use the full name (base_class::member) Private Permission (but we can still use public methods for access)

Accessing the Base Class Data Members

copyrights © Elhanan Borenstein

The derived class also inherit all the base class methods. The derived class can override inherited methods

We can still activate the base method using its full name.

C’tor, D’tor and C.C. are the only methods that have a different behavior when inherited.

Using the Base Class Member Functions

Page 8: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Polymorphism

The Polymorphism mechanism allows for an action to performs differently according to the object type, while being transparent to the programmer.

As we recall, a pointer to the base class can also point to objects from a derived class. There will be no data loss We will be able to activate methods on that object, only if they exist

in the base class.

The issue is however, which method will be activated (base or derive)?

Introduction

copyrights © Elhanan Borenstein

Page 9: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

PolymorphismExample

class Employee{

double Salary; public:

void Print() const {…}void RaiseSalary (double r){

Salary += r;Print();

}};

class Manager : public Employee{

… public:

void Print() {…} };

main (){

Employee *pE;pE = new Manager;pE->Print();…

Manager m;m.Print();m.RaiseSalary();

}

copyrights © Elhanan Borenstein

Page 10: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Polymorphism

When activating a method through a pointer to the base class:

if the method was not defined as virtual: A Static Binding is performed (on compilation) The base class method will be activated

If the method was define as virtual: A Dynamic Binding will be performed (on runtime) The method of the appropriate class will be activated.

Usage: Containers, Generic Algorithms

Virtual Methods and Dynamic Binding

copyrights © Elhanan Borenstein

Page 11: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Polymorphism

There are cases (especially when we implemented a General Container), where there is no intention to actually create an object of the base class.

In such a case, we wish to: Avoid implementation Prevent the programmer from creating objects of the base class.

The solution is Pure Functions and Abstract Classes: A pure function is a virtual function, declared in the base class

only for the purpose of implementing it in the derived classes. To define a function as pure we will add =0 in the prototype.

A class with one or more pure function is automatically an abstract class objects of that class cannot be created or passed ByVal.

Abstract Classes

copyrights © Elhanan Borenstein

Page 12: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Polymorphism

Dynamic binding is implemented by a virtual functions table. Each object that includes a virtual function will also include a

pointer to this table (usually two bytes pointer): Calling a virtual function will thus require two memory calls:

C obj;

How Does Dynamic Binding Work?

class A{

int a; public:

virtual void f() {…}virtual void h() {…}virtual void g() {…}

};

class B : public A{

int b; public:

virtual void g() {…}};

class C : public B{

int c; public:

virtual void h() {…}};

avfptr

bc

A::f()B::g()C::h()

C vftable

copyrights © Elhanan Borenstein

Page 13: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Polymorphism

There are scenarios where we are required to check what is the real object type that we actually hold. (WHEN?)

We can implement our own mechanism using a virtual function called Type().

Alternatively, the operator typeid can be used. #include <typeinfo.h> is required (not an integral part of C++) Setting the project to work with RTTI is required The return value is an object of type typeinfo, that supports the

method name() and the operator == typeid also works on fundamental data types (int, float, etc.)

Runtime Type Information

copyrights © Elhanan Borenstein

Page 14: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

File Handling in C++

copyrights © Elhanan Borenstein

Page 15: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

File Handling Classes

C++ includes special classes for file handling (reading from files / writing to files).

We already had a short example where these classes were used (when overloading the operator >>: ostream – writing to the screen ofstream – writing to a file

C file handling functions (fopen, fprintf, fread, fwrite) can still be used.

NOTE: C file handling functions : “global” functions that get a parameter of type

FILE* C++ file handling functions : methods of a class which represents a file

Working with Files

copyrights © Elhanan Borenstein

Page 16: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

File Handling Classes

When working with files in C++, the following classes can be used: ofstream – writing to a file ifstream – reading for a file fstream – reading/writing (multiple inheritance) …and many other derived and base classes…

What does it all have to do with cout? ofstream inherits from the class ostream (standard output class). ostream overloaded the operator >> for standard output. …thus an ofstream object can use methods and operators defined in

ostream (as we seen in the example). When ever we include <iostream>, an ostream object, pointing to stdout

is automatically defined – this object is cout.

General

copyrights © Elhanan Borenstein

Page 17: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

File Handling ClassesHierarchy Diagram

copyrights © Elhanan Borenstein

Page 18: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

File Handling Classes

A file can be open by the method “open()” or immediately in the c’tor (the natural and preferred way).

void ofstream / ifstream::open(const char* filename, int mode, int prot); filename – file to open (full path or local) mode – how to open (one or more of the following – using | )

ios::app – append ios::ate – open with marker at the end of the file ios::in / ios::out – (the defaults of ifstream and ofstream) ios:nocreate / ios::noreplace – open only if the file exists / doesn’t exist ios::trunc – open an empty file ios::binary – open a binary file (default is textual)

prot – file type (read only, hidden, etc.)

Don’t forget to close the file using the method “close()”

Opening a File

copyrights © Elhanan Borenstein

Page 19: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

File Handling Classes

is_open() – Checking whether the file was open correctly. (for compatibility with C, the operator ! was overloaded).

rd_state() – returns a variable with one or more (check with AND) of the following options: ios::goodbit – OK ios::eofbit – marker on EOF ios::failbit – illegal action, but alright to continue ios:badbit – corrupted file, cannot be used.

We can also access the bit we wish to check with eof(), good(), fail(), bad().

clear() is used to clear the status bits (after they were checked).

Querying a File

copyrights © Elhanan Borenstein

Page 20: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

File Handling Classes

seekg() / seekp() – moving the reading (get) / writing (put) marker two parameters: offset and anchor

tellg() / tellp() – getting the position of the reading (get) / writing (put) marker

Moving within the File

copyrights © Elhanan Borenstein

Page 21: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

File Handling Classes

To write: put() – writing single character << operator – writing an object

To read: get() – reading a single

character of a buffer getline() – reading a single line >> operator – reading a object

Reading /Writing from/to Textual Files

copyrights © Elhanan Borenstein

#include <fstream.h>main(){

// Writing to fileofstream OutFile("my_file.txt");OutFile<<"Hello "<<5<<endl;OutFile.close();

int number;char dummy[15];

// Reading from fileifstream InFile("my_file.txt");InFile>>dummy>>number;

InFile.seekg(0);InFile.getline(dummy, sizeof(dummy));InFile.close();

}

Page 22: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

File Handling Classes

To write n bytes: write (const unsigned char* buffer, int n);

To read n bytes (to a pre-allocated buffer): read (unsighed char* buffer, int num) Use: int gcount() to check how many byte where actually read (WHY) Note: Unlike C, the buffers are of type unsigned char* (and not void*)

Reading /Writing from/to Binary Files

copyrights © Elhanan Borenstein

#include <fstream.h>main(){

int array[] = {10,23,3,7,9,11,253};ofstream OutBinaryFile("my_b_file.txt“, ios::out | ios::binary);OutBinaryFile.write((char*) array, sizeof(array));OutBinaryFile.close();

}

Page 23: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Polymorphism & Files

Serialization

copyrights © Elhanan Borenstein

Page 24: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Serialization

Serialization is a common method to store (save) and retrieve (load) data objects. It can be used to save database records, the status of the application, etc.

In C: we could store all the required fields in structures and then use

fread/fwrite to store this data in a binary file. Important – pointers should not be stored (as they will be invalid

when we load them. Instead, whenever a dynamic allocation was used, the file should store the size of the allocation and then the content (and load appropriately).

In C++: the same mechanism is use but naturally using Classes, Polymorphism and Object Oriented paradigm.

Introduction

copyrights © Elhanan Borenstein

Page 25: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Serialization in C++

Each class we wish to be able to store, will have a Save() method (this

method will handle saving the object data members to the file). Save() will get as parameter an object of type ofstream. If the object includes dynamic allocations, it should not store the pointer, but

rather the size of the allocated memory and its content. Note: if the class includes (or inherits) virtual functions, the pointer to the vf table

should not be saved. A derived class can (and should) use the base class Save method (e.g.

base_name::Save()) to store the base data members and only then save the new derived members.

Each such class will also have: A Load C’tor that gets as a parameters an object of type ifstream and builds a

new object according to the data in the file A Load() method that can read the data to an existing object. When loading a dyn. allocated member, a new allocation is made.

Saving & Loading Objects

copyrights © Elhanan Borenstein

Page 26: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Serialization in C++

When using a general container (which holds objects of various classes with a common base class) we wish to be able to use the Save() method transparently. Thus,

we will define the Save() method in the base class as virtual. The container should also implement a Save() method which will

traverse all the objects it holds and call their Save() method.

What about the container Load() method? The container has to “know” which objects should be created. It is thus common to store in the file, before each object a code

(textual, binary, etc.) which will identify the object type. The container Load() method, will first read this code and then create the appropriate object.

Branching should be performed wisely (switch, hash table, etc.)

Using Containers

copyrights © Elhanan Borenstein

Page 27: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Serialization in C++

We wish to implement a data base which will allow the user to input / print / save / load the list of employees in the company.

For each employee in the company we wish to store: Name (char*), Salary (float)

Some of the employees are managers. Manager record should also include: Level (int)

Obviously, we wish to have as little as possible locations where we distinct between employees and managers.

Example: Human Resources – Data Base

Example

copyrights © Elhanan Borenstein

Page 28: Object Oriented Programming Elhanan Borenstein borens@tau.ac.il Lecture #8 copyrights © Elhanan Borenstein

Questions?

copyrights © Elhanan Borenstein