Presentation is loading. Please wait.

Presentation is loading. Please wait.

Object Oriented Programming Elhanan Borenstein Lecture #8 copyrights © Elhanan Borenstein.

Similar presentations


Presentation on theme: "Object Oriented Programming Elhanan Borenstein Lecture #8 copyrights © Elhanan Borenstein."— Presentation transcript:

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

2 Agenda Inheritance & Polymorphism – A short reminder File Handling in C++ Polymorphism & Files: Serialization copyrights © Elhanan Borenstein

3 Inheritance & Polymorphism a Short Reminder copyrights © Elhanan Borenstein

4 Inheritance Example class Base1 { int var1; public: Base1() {…} // constructor void OldFunc() {…} void Init() {…} }; class Derived1 : [public|protected|private] Base1 { int var2; public: Derived1() {…} // constructor void Init() {…} // override void Do(){…} }; copyrights © Elhanan Borenstein

5 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) Additions Derived (son)  (SIZE?) Additions embedding class inner object copyrights © Elhanan Borenstein

6 Inheritance Understanding Inheritance - Example class GraphicItem { int color; public: GraphicItem() {…} // constructor void Draw() {…} void ChangeColor(int n_clr) {…} }; class CPoint : public GraphicItem { int m_x, m_y; public: CPoint() {…} // constructor void Draw() {…} // override void Align(){…} }; … GraphicItem G, *pG; CPoint P, *pP; … G = P; P = G; pG = pP; pP = pG; … copyrights © Elhanan Borenstein

7 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

8 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

9 Polymorphism Example 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

10 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

11 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

12 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() {…} }; a vfptr b c A::f() B::g() C::h() C vftable copyrights © Elhanan Borenstein

13 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 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

14 File Handling in C++ copyrights © Elhanan Borenstein

15 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

16 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, an ostream object, pointing to stdout is automatically defined – this object is cout. General copyrights © Elhanan Borenstein

17 File Handling Classes Hierarchy Diagram copyrights © Elhanan Borenstein

18 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

19 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

20 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

21 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 main() { // Writing to file ofstream OutFile("my_file.txt"); OutFile<<"Hello "<<5<<endl; OutFile.close(); int number; char dummy[15]; // Reading from file ifstream InFile("my_file.txt"); InFile>>dummy>>number; InFile.seekg(0); InFile.getline(dummy, sizeof(dummy)); InFile.close(); }

22 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 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(); }

23 Polymorphism & Files Serialization copyrights © Elhanan Borenstein

24 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

25 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

26 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

27 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

28 Questions? copyrights © Elhanan Borenstein


Download ppt "Object Oriented Programming Elhanan Borenstein Lecture #8 copyrights © Elhanan Borenstein."

Similar presentations


Ads by Google