object oriented programming language by c++


Published on

slides cane make your under standing for the OOP "useing c++ " essayer than any other slides
by :dr.wa'ael al qassas
edited by mohamad al maane

Published in: Technology

object oriented programming language by c++

  1. 1. Object Oriented Programming ‫وائل قصاص‬ 1
  2. 2. Course Outline Introduction to Object Oriented Programming (OOP): Overview of programming languages. * What is object Oriented? * Benefits of Object Oriented. * What is an object? * What is a class? * Black boxes and interfaces. * Attributes and methods. * What is abstract class (abstraction)? classesClass fundamentals. * A closer look at class member access. * Constructors and destructors. * Parameterized constructors. * Classes and structures are related. * Unions and classes are related. * Inline functions. * Creating inline functions inside a class. * Arrays of object. * Pointers to object. * Object references. ‫وائل قصاص‬ 2
  3. 3.  Friend functionsFriend functions. * Overloading constructor functions. * Dynamic initialization. * Assigning objects. * Passing objects to functions. * Returning objects. * Creating and using copy constructor. * The this keyword. Operator OverloadingOperator Overloading using member functions. * Friend operator functions. * A closer look at the assignment operator. * Overloading new and delete. * Overloading []. * Overloading other operators. InheritanceIntroducing inheritance. * Base class access control. * Using protected members. * Inheriting Multiple Base Classes. * Constructors, destructors, and inheritance. * Granting access. * Virtual base class. Virtual functions and polymorphismPointers to derived class. * Virtual functions. * Virual functions are inherited. * Pure virual functions and Abstract classes. * Early versus late binding. Templates and Exception handlingGeneric functions. * A function with two generic types. * Exception handling. * Options for exception handling. * Generic classes. * Eception Handling. * Using Multiple catch statements. * Catching all exceptions.
  4. 4. Text book and references Title : C++ How to Program Author(s) Paul J. Deitel, Harvey M. Deitel Edition : 4th Publisher : Prentice Hall************************************************************* Title : C++ From the GROUND UP Author(s) R. Schildt Edition: 3rd Pubisher: McGraw-Hill ‫وائل قصاص‬ 4
  5. 5. • First Exam 15 • Second Exam 15 • Lab 20 • Final Exam 50Grading Policy ‫وائل قصاص‬ 5
  6. 6. Classes and Data AbstractionA class is a logical method to organize data and operations (functions) on that data in the same unit (called class). They are declared using keyword class, functionality is similar to that of the C keyword struct with some difference. Its general form is: class class_name { permission_label_1: member1; permission_label_2: member2; ... } object_name; where class_name is a name for the class (user defined type) and the optional field object_name is one, or several, valid object identifiers.
  7. 7.  The body of the declaration can contain members, that can be either data or function declarations, and optionally permission labels, that can be any of these three keywords: private:, public: or protected:. A reference to the permission which the following members acquire:  private members of a class are accessible only from other members of their same class or from their "friend" classes. protected members are accessible from members of their same class and friend classes, and also from members of their derived classes.  public members are accessible from anywhere the class is visible. ‫وائل قصاص‬ 7
  8. 8. When declaring members of a class before including any permission label, the members are considered private, since it is the default permission that the members of a class declared with the class keyword acquire. For example: class CRectangle { int x, y; //x,y are considered private members public: void set_values (int,int); int area (void); } rect; ‫وائل قصاص‬ 8
  9. 9.  Declares class CRectangle and an object called rect with four members: two variables of type int (x and y) in the private section (because private is the default permission) and two functions in the public section: set_values() and area(), of which only the prototype are included. Any of the public members of the object rect could be referred to just by putting the objects name followed by a point and then the class member  rect.set_value(3,4); myarea = rect.area();  but it is not possible to refer to x or y since they are private members of the class and they could only be referred to from other members of that same class.
  10. 10. ‫وائل قصاص‬ ‫01‬
  11. 11.  The operator :: of scope (called scope of resolution) included in the definition of set_values(). It is used to declare a member of a class outside it. Notice that we have defined the behavior of function area() within the definition of the CRectangle class given its extremesimplicity. Whereas set_values() has only its prototype declared within the class but its body definition is outside. In this outside declaration we must use the operator of scope ::  The scope operator (::) specifies the class to which the member being declared belongs. ‫وائل قصاص‬ 11
  12. 12.  The reason why x and y are made private members is because sometimes it is important that values cannot be modified in an unexpected way from outside the class (i.e. via client code). To access these variables this can be done through member functions that are declared as public.  In the previous example, we have already defined a function to introduce those values in the object (set_values()) and therefore the rest of the program does not have a way to directly access them. Several different objects can be defined from one class. ‫وائل قصاص‬ 12
  13. 13. #include< iostream.h>#include <cstring> Exampleclass student { char name[20]; int First,second,final,total,ID; int calculate_total( ); public: student() { strcpy(name,"AHMAD"); ID=900901123; First=second=final=0; } int get_total(){return total;} void print(void) {cout<<name<<"t"<<ID<<"t"<<calculate_total( )<<endl;}}; // end of class definitionint student::calculate_total( ){total=First+second+final; return total;} ‫وائل قصاص‬ 13
  14. 14. void main(){student st; cout<<st.get_total(); st.print(); st.print();} ‫وائل قصاص‬ 14
  15. 15. The call to rect.area( ) does not give the same result as the call to rectb.area( ), each object of class CRectangle hasits own variables x and y, and its own functions set_value() and area(). functions are properties of the object, instead ofthe usual view of objects as function parameters in structuredprogramming. In this concrete case, the class (type of object) ‫وائل قصاص‬ 15 is CRectangle, of which there are two instances, or
  16. 16. Quiz Design a class named Student that has a name, ID, first,second, final and Total marks. This class has a calculate_total method which is has a private permission The class has set_Name_ID( char[ ],int) method that stores the name of the student The class has set_marks(int,int,int) method The class has print( ) method that calls the calculate_total and then prints the student name , student ID and student total mark. The main function looks like this: void main( ){ Student St; St.set_Name_ID(“Ahmad”,1000901123); St.set_marks(19,21,41); St.print( ); } ‫وائل قصاص‬ 16
  17. 17. Example: // Example on class 22-feb-2012 #include< iostream.h> #include <cstring> class Student { char name[20]; int first,second,final,total,ID; void calculate_total( ); public: void Set_Name_ID(char n[ ],int id) { strcpy(name,n); ID=id;} void Set_marks(int ,int ,int ); void print(void) { calculate_total( ); cout<<name<<"t"<<ID<<"t"<<total<<endl;} }; // end of class definition ‫وائل قصاص‬ 17
  18. 18. Example: void Student::calculate_total( ) {total=first+second+final;} void Student::Set_marks(int x,int y,int z) { first=x; second=y; final=z;} void main( ){ Student St; St.Set_Name_ID("Ahmad",1000901123); St.Set_marks(19,21,41); St.print( ); } ‫وائل قصاص‬ 18
  19. 19. Constructors and Destructors  Objects generally need to initializevariables or assign dynamic memory during their process of creation to become totally operative and to avoid returning unexpected values during their execution.  what would happen if in the previous example the function area() is called before having called function set_values? Probably an undetermined result since the members x and y would have never been assigned a value. In order to avoid that, a class can include ‫وائل قصاص‬ 19
  20. 20. Example: “A construct or never returns a value nor does the void have to be specified”
  21. 21.  For the student example add a constructor method that prints a message indicating that an object has been constructed. ‫وائل قصاص‬ 21
  22. 22. class Student { char name[20]; Example int first,second,final,total,ID; on Constructors void calculate_total( ); public: Student( ) { cout<<"An object has been constructedn";} void Set_Name_ID(char n[ ],int id) { strcpy(name,n); ID=id;} void Set_marks(int ,int ,int ); void print(void) { calculate_total( ); cout<<name<<"t"<<ID<<"t"<<total<<endl;} }; // end of class definition ‫وائل قصاص‬ 22
  23. 23. Example: void Student::calculate_total( ) {total=first+second+final;} void Student::Set_marks(int x,int y,int z) { first=x; second=y; final=z;} void main( ){ Student St; St.Set_Name_ID("Ahmad",1000901123); St.Set_marks(19,21,41); St.print( ); } ‫وائل قصاص‬ 23
  24. 24.  Modify the constructer so that it gives a default values to name “ No name”, ID=0, first,second and final are also 0Student( ){strcpy(name,”No name”) ;ID=0;first=second=final=0;} ‫وائل قصاص‬ 24
  25. 25.  Overload the constructor so it can take the name and the ID at the creation of the instance. Also let id has a default value equal to zero Student (char n[ ],int id=0) { strcpy(name,n); ID=id; first=second=final=0;}In the mainStudent St2("Ali");St2.print(); ‫وائل قصاص‬ 25
  26. 26. Example: Empty Constructor If we didn’t define a constructor then there is an empty constructor as default Also there is a default copy_constructor that allow copying one constructor to another.void main( ){Student St1;St1.print();St1.Set_Name_ID("Ahmad",1000901123);St1.Set_marks(19,21,41);St1.print( );Student St2;St2=St1;St2.print();} ‫وائل قصاص‬ 26
  27. 27.  With no constructors, the compiler automatically assumes that it has empty constructor:  Empty constructor: It is a constructor with no parameters defined as empty block of instructions. It does nothing. The empty construction exists only if no other constructor is explicitly declared. In case that any constructor with any number of parameters is declared, the default constructor is not called.  CExample::CExample () { }; To copy one instance of class to another, Copy constructor is needed: when ever one object assigned to another we are making a copy of it. There are two types of copy constructor. ◦ Perform simple variable by variable assignment: copy of all the components of one object to another. ◦ Passing an object to a function. It is a constructor with one parameter of same type that
  28. 28. CExample::CExample (const CExample& rv) create a new object of class CExample (rv) {a=rv.a; b=rv.b; c=rv.c;}  In the example above, a new object of class CExample is created and which is a copy of the passed object, then in the implementation part will initialize the data members of the current object with the rv data ‫وائل قصاص‬ 28
  29. 29. Overloading Constructors A constructor can also be overloaded with several functions that have the same name but different types or numbers of parameters.  In the cases where a class is declared and no constructor is specified, the compiler automatically assumes two overloaded constructors ("default constructor" and "copy constructor"). For example, for the ‫وائل قصاص‬ class: 29 class CExample { public:
  30. 30. ‫:‪Example‬‬ ‫وائل قصاص‬ ‫03‬
  31. 31.  In this case rectb was declared without parameters, so it has been initialized with the constructor that has no parameters, which declares both width and heightwith a value of 5. Notice that if we declare a new object and we do not want to pass parameters to it we do not include parentheses ( ):  CRectangle rectb; // right ‫وائل قصاص‬ 31 
  32. 32. Destructor The Destructor is automatically called when an object is released from the memory in two cases: 1. Its scope of existence has finished (i.e, if it was defined as a local object within a function and the function ends) 2. Object dynamically assigned and it is released using delete operator. The destructor must have the same name as the class with a
  33. 33.  Build a Destructor that prints a messege denoting when an object is being distructed~Student(){cout<<name<<"nAn object has been destructedn";} ‫وائل قصاص‬ 33
  34. 34. Example on destructionvoid F(Student S){Student S1;S1=S;S.Set_marks(25,25,50);S.print();S1.print();}void main( ){Student St1,St2;St1.Set_Name_ID("Ahmad",1000901123);St2.Set_Name_ID("Ali",1000902321);F(St1);cout<<"back from functionn";} ‫وائل قصاص‬ 34
  35. 35.  The new keyword allocate memory dynamically at run time , so that the records are allocated while execution There is a direct relationship between new and pointer.new , delete keywords ‫وائل قصاص‬ 35
  36. 36. Example: #include <iostream.h> void main() { int *p1, *p2; p1=new int; *p1=10; cout<<&p1<<endl; // location of the pointer cout<<"Memory location "<<p1<<" contains " <<*p1<<endl; p2=new int; *p2=10; cout<<&p2<<endl; // location of the pointer cout<<"Memory location "<<p2<<" contains "<<*p2<<endl; delete p1; delete p2; } ‫وائل قصاص‬ 36
  37. 37. 0x0012FF7CMemory location 0x00901F80 contains 100x0012FF78Memory location 0x00901D20 contains 10Press any key to continueOutput ‫وائل قصاص‬ 37
  38. 38. Example: #include <iostream.h> void main() { int *p1, *p2; p1=new int; *p1=10; cout<<&p1<<endl; // location of the pointer cout<<"Memory location "<<p1<<" contains " <<*p1<<endl; delete p1; p2=new int; *p2=10; cout<<&p2<<endl; // location of the pointer cout<<"Memory location "<<p2<<" contains "<<*p2<<endl; delete p2; } ‫وائل قصاص‬ 38
  39. 39.  0x0012FF7C Memory location 0x00901F80 contains 10 0x0012FF78 Memory location 0x00901F80 contains 10 Press any key to continue ‫وائل قصاص‬ 39
  40. 40. // example on constructors and destructors#include <iostream.h>class CRectangle { int *width, *height; public: CRectangle (int,int); // constructor ~CRectangle (); //destructor int area (void) {return (*width * *height);} }; CRectangle::CRectangle (int a, int b) { width = new int; height = new int; *width = a; *height = b;} CRectangle::~CRectangle () { delete width; delete height;} int main () { CRectangle rect (3,4), rectb (5,6);  Example: cout << "rect area: " << rect.area() << endl; 40 cout << "rectb area: " << rectb.area() << endl; ‫وائل قصاص‬
  41. 41. An inline function is a function that is expanded in line at the point at which it is invoked, instead of actually being called. The reason for inline function is efficiency. There are two ways to create an inline function.The first : to use the inline modifier.inline int f(){//……..Inline functions} ‫وائل قصاص‬ 41
  42. 42.  Every time a function is called, a series of instructions must be executed, both to set up the function call, including pushing any arguments onto the stack, and to return from the function. In somecases, many CPU cycles are used to perform these procedures. However, when a function is expanded in line, no such overheadexists, and the overall speed of your program will increase. ‫وائل قصاص‬ 42 
  43. 43. class c1 { int i;  If you compile this public: version of the program, int get_i(); save its object code, and void put_i(int j);}; then compile it again withinline int c1::get_i() the inline specifier { return i;} removed, you will see theinline void c1::put_i(int j) inline version is several { i=j;} bytes smaller.  Inline is a request not avoid main(){ c1 s; command, that the s.put_i(10); compiler generate inline cout<<s.get_i();} code.output example  Some compilers will not10 generate inline code if a function contains a loop, a
  44. 44.  Second :Creating Inline Functions inside a ClassAny function that is defined inside a class definition is automatically made into an class c1 { function. It is not necessary to inline precede int i; declaration with the keyword its public: //automatic inline functions. inline. int get_i() {return i;} void put_i(int j) {i=j;} }; int main() { c1 s; s.put_i(10); Output 10 cout<<s.get_i(); return 0;} ‫وائل قصاص‬ 44
  45. 45.  www.facebook.com/groups/oop.a Face book group ‫وائل قصاص‬ 45
  46. 46.  The keyword enum creates a user-defined type Examples:enum semesters {first, second, summer};enum months{jan=1,feb,mar,apr,may,jun,jul,aug,sept, oct,nov,dec}; If you print enum variable, the output will be an integer that represents the order of the value in the definition starting from 0 For the second example the counting will start from 1 You cant read an enum by cin You cant make arithmatic operations on enum You can only assign a value for the enum by using = , and make relational operations on enumEnumeration in C++ ‫وائل قصاص‬ 46
  47. 47. Example: #include <iostream.h> void main(){ enum mark {pass, fail}; mark m; int score; cout<<"Enter your mark "; cin>>score; if (score>=50) m=pass; else m=fail; if( m==pass) cout<<" you passed the examn"; else cout<<"you failed in the examn"; } ‫وائل قصاص‬ 47
  48. 48. Array of objects can be created in the same way that you create arrays of any other data types.3.3 Array of object and Pointers toObjects ‫وائل قصاص‬ 48
  49. 49. ‫وائل قصاص‬ ‫94‬
  50. 50. Example: It is perfectly valid to create pointers pointing to classes, in order to do that, simply consider that once declared, the class becomes a valid type, so use the class name as the type for the pointer. ‫وائل قصاص‬ 50
  51. 51.  (*p).show_num(); and p->show_num(); are the same *p can be read: pointed by p &x can be read: address of x x.y can be read: member y of object x (*p).y can be read: member y of object pointed by p p->y can be read: member y of object pointed by p (equivalent to the previous one) x[0] can be read: first object pointed by x x[1] can be read: second object pointed by x x[n] can be read: (n+1)th object pointed by x ‫وائل قصاص‬ 51
  52. 52. If there is array of objects are to be defined, and there exist a constructor, then the declaration will be: class_name obj[n]={values of initialization}#include <iostream.h> 10class p_example { 20 int num;public: p_example(int a){num=a;} void set_num(int val) {num=val;} void show_num( );}; void p_example::show_num() {cout<<num<<“n”;}void main(){ p_example ob[2]={10,20}; ob[0]. show_num(); ob[1]. show_num();}  Example: 52 ‫وائل قصاص‬
  53. 53. class Student { char name[20]; int first,second,final,total,ID;public: Another Student( ) //constructor example {strcpy(name,"No name") ; ID=0; on array first=second=final=0; } Student(char n[ ],int id) //constructor overloading {strcpy(name,n) ; ID=id; first=second=final=0;} void print(void) {cout<<name<<"t"<<ID<<"t"<<total<<endl;} }; // end of class definition ‫وائل قصاص‬ 53
  54. 54. Example: void main( ) { Student S1("Ali",123),S2("Ahmad",456); Student St[3]={S1,S2}; for (int i=0;i<3;i++) St[i].print(); } ‫وائل قصاص‬ 54
  55. 55. Example: void main( ) { Student S1("Ali",123),S2("Ahmad",456), *SP; Student St[3]={S1,S2}; SP=St; for (int i=0;i<3;i++) (SP+i)->print(); } Rewrite the main in the prev. example with pointers ‫وائل قصاص‬ 55
  56. 56. Example: void main( ) { Student S1("Ali",123),S2("Ahmad",456), *SP; Student St[3]={S1,S2}; SP=St; for (int i=0;i<3;i++) SP++->print(); } Rewrite the main in the prev. example with pointers ‫وائل قصاص‬ 56
  57. 57. Static Class Member Each object has its own copy of all data members of the class. If a data item in a class defined as static, then only one such item is created for the entire class, no matter how many objects there are. ‫وائل قصاص‬ 57
  58. 58. Example: // Example on class 29-feb-2012 #include< iostream.h> #include <cstring> class Student { static int count; char name[20]; int first,second,final,total,ID; public: Student( ) //constructor {strcpy(name,"No name") ; ID=0; first=second=final=0; count++; cout<<"Numbers of students constructed :"<<count<<endl;} }; // end of class int Student::count=0; void main( ) { cout<<"nConstruct 2 objectsn"; Student S1,S2; cout<<"nConstruct 3 objectsn"; Student St[3]; } // end of main ‫وائل قصاص‬ 58
  59. 59. Construct 2 objectsNumbers of students constructed : 1Numbers of students constructed : 2Construct 3 objectsNumbers of students constructed : 3Numbers of students constructed : 4Numbers of students constructed : 5Press any key to continue The Output will be: ‫وائل قصاص‬ 59
  60. 60. Example: #include <iostream.h> class st_example { static int count; public: st_example (){count++;} int get_count(){return count;}}; count is1 int st_example::count=0; count is2 void main() count is2 { st_example ob1; count is3 cout<<”n count is”<<ob1.get_count(); st_example ob2; cout<<”n count is”<<ob1.get_count(); cout<<”n count is”<<ob2.get_count(); st_example ob3; cout<<”n count is”<<ob3.get_count(); } ‫وائل قصاص‬ 60
  61. 61.  This type of function can be accessed in two ways: 3. Through any object of that class (ob1.get_count()).4. Or through the class name using the binary scope of resolution (::) directly (cout<<st_example ::get_count();).Static Member Function ‫وائل قصاص‬ 61
  62. 62. class Student { static int count; char name[20]; int first,second,final,total,ID; public:static void print_count(){cout<<“Students constructed: “ <<count<<endl;} Student( ) //constructor {strcpy(name,"No name") ; ID=0; first=second=final=0; count++; print_count(); } }; // end of class int Student::count=0;void main( ){ Student::print_count(); cout<<"nConstruct 2 objectsn"; Student S1,S2; cout<<"nConstruct 3 objectsn"; Student St[3];} ‫وائل قصاص‬ 62
  63. 63. Numbers of students constructed : 0Construct 2 objectsNumbers of students constructed : 1Numbers of students constructed : 2Construct 3 objectsNumbers of students constructed : 3Numbers of students constructed : 4Numbers of students constructed : 5Press any key to continueOutbot ‫وائل قصاص‬ 63
  64. 64. Example: #include <iostream.h> class st_example { static int count; public: st_example (){count++;} static int get_count(){return count;}}; count is1 int st_example::count=0; count is2 void main() count is2 { st_example ob1; count is3 cout<<”n count is”<<ob1.get_count(); st_example ob2; cout<<”n count is”<< st_example ::get_count(); cout<<”n count is”<<ob2.get_count(); st_example ob3; cout<<”n count is”<<ob3.get_count(); } ‫وائل قصاص‬ 64
  65. 65. Constant Object & Constant Member FunctionThe keyword const is used in C language to define a data values that cannot be changed during program execution. In OOP, const could be used to specify constant object and / or constant member function. ‫وائل قصاص‬ 65
  66. 66. #include <iostream.h>class time {private:int h,m,s;public: void print() const; //constant function time(int i, int j, int k){h=i; m=j; s=k;}};void main(){ const time noon(12,0,0); //constant object:} Keyword const is used to specify non modifiable objects, and any attempt to modify the const object cause syntax error. const time noon(12,0,0);// indicates constant object noon of class time which is initialized to 12 noon. ‫وائل قصاص‬ 66
  67. 67. Constant Member Function  Constant function could be defined as follows: At prototype: type function_name() const ; At implementation : type function_name() const { }; Notes: * It is not allowed for any member_function calls for const object unless the member functions also constant. * Constant member functions cannot modify the object. * It is not allowed to declare constructors as constant since it allow to modify objects ‫وائل قصاص‬ 67
  68. 68. Example:#include <iostream.h>class time {private:int h,m,s;public: 12:0:0 void print() const {cout<<h<<”:”<<m<<”:”<<s; } time(int i, int j, int k) {h=i; m=j; s=k;} int get_h() {return h;}};void main(){ const time noon(12,0,0); noon.print(); // cout<<noon.get_h(); //error since get_h not const} ‫وائل قصاص‬ 68
  69. 69. Friends (friend keyword) There are three levels of internal protection for the different members of a class: public, protected and private.  In the case of members protected and private, these could not be accessed from outside the same class at which they are declared. Nevertheless, this rule can be transgressed with the use of the friend keyword in a class, so we can allow an external function to gain access to the protected and private members of a class. ‫وائل قصاص‬ 69
  70. 70. Friend Functions  In order to allow an external function to have access to the private and protected members of a class, declare the prototype of the external function that will gain access by the keyword friend within the class declaration that shares its members. ‫وائل قصاص‬ 70
  71. 71. Example: class myclass { int a, b; public: myclass(int i, int j) {a=i;b=j;} friend int sum(myclass x); }; // note: sum() is not a member function of any class int sum(myclass x) { //sum() is a friend of myclass, it can access a and b through object x return x.a+x.b;} int main() { myclass n(3,4); cout<<sum(n); return 0;} ‫وائل قصاص‬ 71
  72. 72. #include <iostream.h>class CRectangle { int width, height; public: void set_values (int, int); int area (void) {return (width * height);} friend CRectangle duplicate (CRectangle); }; // End of Class24def. void CRectangle::set_values (int a, int b) { width = a; height = b; }CRectangle duplicate (CRectangle R){ CRectangle T;T.width = R.width*2;T.height = R.height*2;return (T); }void main () { CRectangle rect, rectb; rect.set_values (2,3); rectb = duplicate (rect); cout << rectb.area(); } ‫وائل قصاص‬ 72
  73. 73.  The use of friend functions is out of an OOP methodology, so it is preferable to use members of the same class to make the process. As in the previous example, it would have been shorter to integrate duplicate() within the class CRectangle. A function may be a friend of more than one class. ‫وائل قصاص‬ 73
  74. 74. #include <iostream.h>const int IDLE =0;const int INUSE=1;class c2; //forward referenceclass c1 { int status; public: void set_status(int state); friend int idle(c1 a, c2 b); };class c2 { int status; Screen can be used public: Pop up in use void set_status(int state); friend int idle(c1 a, c2 b); };void c1::set_status(int state) { status=state; }void c2::set_status(int state) { status=state; }int idle(c1 a, c2 b) {if(a.status || b.status) return 0; else return 1; }void main(){ c1 x; c2 y; x.set_status(IDLE); y.set_status(IDLE); if ( idle(x,y) ) cout<<“screen can be usedn”; else cout << “Pop-up In usen”; x.set_status(INUSE); if ( idle(x,y) ) cout <<“Screen can be usedn”; else cout <<“Pop-up in usen”;} ‫وائل قصاص‬ 74
  75. 75.  we can define a class as friend of another one, allowing that the second one access to the protected and private members of the first one.Friend Classes (friend) ‫وائل قصاص‬ 75
  76. 76. #include <iostream.h>class CSquare;class CRectangle { int width, height; public: int area (void) {return (width * height);} void convert (CSquare a); };class CSquare { 16 private: int side; public: void set_side (int a) {side=a;} friend class CRectangle; };void CRectangle::convert (CSquare a) { width = a.side; height = a.side; }void main () {CSquare sqr;CRectangle rect; sqr.set_side(4); rect.convert(sqr); cout << rect.area(); } ‫وائل قصاص‬ 76
  77. 77.  CRectangle is declared as a friend of CSquare so that CRectangle can access the protected and private members of CSquare, more concretely CSquare::side, that defines the square side width. In the first instruction of the program, the empty prototype of class CSquare is used. This is necessary because within the declaration of CRectangle, we refer to CSquare (as a parameter in convert()). ‫وائل قصاص‬ 77
  78. 78.  Function Overloading Struct: Classes: Public, private, scope operator (::) Empty constructor , Copy constructor Constructor Destructor New delete keywords and its relation with Constructor and destructor Inline function Enum Arrays of objects and relation with pointers Static object Static function Const Object Const member function. Friend function Friend ClassTopic covered up to now ‫وائل قصاص‬ 78
  79. 79. Dynamic initialization In c++, both local and global variables can initialized at run time. This process is sometimes referred to as Dynamic initialization. Most initializations have used constants. Under Dynamic initialization, a variable can be initialized at run time using any c++ expression valid at the time the variable is declared. You can initialize a variable using other variables.The following are all perfectly valid variables initializations in c++:int n = strlen(str);double arc = sin(theta);float d= 1.02 * count / deltax; ‫وائل قصاص‬ 79
  80. 80. Applying Dynamic Initialization toConstructors#include <iostream.h>class myclass { int a, b;public: void setab(int i, int j) {a=i; b=j;} void showab(); };void myclass::showab() { obj1 befor assignment: cout << "a is " <<a << "n"; a is 10 cout<< "b is " << b << "n";}main() b is 20{myclass obj1, obj2; ob2 before assignment:obj1.setab(10, 20);obj2.setab(0,0); a is 0cout<<"obj1 before assignment:n"; b is 0obj1.showab();cout<< "obj2 before assignment: n"; ob1 after assignment:obj2.showab(); a is 10cout<< "n"; b is 20obj2=obj1;// assign ob1 to obj2cout<<"obj1 after assignment: n"; Ob2 after assignment:obj1.showab(); a is 10cout<<"obj2 after assignment: n";obj2.showab();} b is 20 ‫وائل قصاص‬ 80
  81. 81.  Like simple variables, objects can be initialized dynamically when they are created. This feature allows you to create exactly the type of object you need, using information that is known only at run time. The point of overloading constructor functions is to help programmers handle greater complexity by allowing objects to be constructed in the most natural manner relative to be used. Assigning Objects: you can assign object to another if both objects of the same type (both are of the same class). It is not sufficient for the two classes to simply be physically similar-their type names must be the same. When one object is assigned to another, the first object data is copied to the second. ‫وائل قصاص‬ 81
  82. 82. #include <iostream.h>class C1{ int x,y;public: C1(){} C1(int a,int b) {x=a;y=b;}}; //End of Class C1class C2{ int x,y;public: C2(){} C2(int a,int b) {x=a,y=b;} }; //End of Class C2void main(){ C1 L,M(10,20); C2 N,P; L=M; N=P; N=M; //Error no acceptable conversion } //End of main ‫وائل قصاص‬ 82
  83. 83. Passing Objects to Functions An object can be passed to a function in the same way as any other data type. Objects are passed to functions using the normal c++ call-by-value parameter passing convention. This means that a copy of the object, not the actual object itself, is passed to the function. Any change made to the object inside the function does not affect the object used as argument to the function. ‫وائل قصاص‬ 83
  84. 84. #include <iostream.h>class OBJ { int i;public: void set_i(int x) { i = x;} void out_i() {cout << i << " ";}}; 10 100 10void f(OBJ x) { x.out_i(); // outputs 10; x.set_i(100); // this affects only local copy x.out_i();} // outputs 100;void main(){ OBJ o; o.set_i(10); f(o); o.out_i(); // still outputs 10, value of I unchanged} ‫وائل قصاص‬ 84 The Modification of x within f() has no effect on object o inside main()
  85. 85. Constructors, Destructors, and Passing Objects Passing simple objects as arguments to functions is a straightforward procedure. #include <iostream.h> class myclass { int val; Constructing public: 10 myclass(int i) Destructing { val=i; cout<<“Constructingn”;} Destructing ~myclass() {cout <<“Destructingn”;} int getval() { return val;}}; void display(myclass ob) { cout<<ob.getval()<<“n”;} void main() { myclass a(10); display (a);}
  86. 86.  As you can see, there is one call to the constructor function (as expected), but there are two calls to the destructor. Why? When an object is passed to a function, a copy of that object is made (and this copy becomes the parameter in the function). This means that a new object comes into existence. Also, when the function terminates, the copy of the argument (i.e., the parameter) is destroyed. This raises two questions: first, is the object’s constructor called when the copy is made? Second, is the object’s destructor called when the copy is destroyed? ‫وائل قصاص‬ 86
  87. 87.  When a copy of an argument is made during a function call, the constructor function is not called. because the constructor function is generally used to initialize some aspect of an object, it must not be called to make a copy of an already existing object that is being passed to a function. When passing an object to a function, you want to use the current state of the object, not its initial state. When the function terminates and the copy is destroyed, the destructor function is called. This is because the object might perform some operations that must be undone when it goes out of scope. For example the copy may allocate memory that must be released. Finally when a copy of an object is created to be used as an argument to a function, the constructor function is not called. When the copy is destroyed (usually by going out of scope when the function returns), the destructor function is called.
  88. 88. A potential problem when passingobjects  If an object used as an argument allocates dynamic memory and frees that memory when it is destroyed, then its local copy inside the function will free the same memory when its destructor is called. This will leave the original object damaged and effectively useless so the abort screen will appear. ‫وائل قصاص‬ 88
  89. 89. #include <iostream.h>#include <stdlib.h>class myclass { int *p;public: myclass(int i); ~myclass(); int getval(){return *p;}};myclass::myclass(int i) { cout<<"allocating pn"; p=new int; if (p==NULL) { cout<<"allocating failure"; exit(1);} //exit program if out of memory *p=i;} Abort screenmyclass::~myclass() { cout<<"Freeing pn"; delete p;}//This will cause a problem.void display(myclass ob) { // try to use &ob what will happen?? cout<<ob.getval()<<"n"; }void main(){ myclass a(10); display(a);} ‫وائل قصاص‬ 89
  90. 90.  Each time a member function is invoked, it is automatically passed a pointer, called this, to the object that has invoked. The "this" pointer is an implicit parameter to all member functions. Therefore, inside a member function, this may be used to refer to the invoking object. For the following example:class c1 {int i; void load_i(int val){i=val;)}; i=val; statement can be used in a member function (load_i ) to assign i the value of val. In actuality, the preceding statement is shorthand for: this->i=10;This ‫وائل قصاص‬ 90
  91. 91. #include <iostream.h>class c1 { int i;public: void load_i(int val) {this->i=val;} // same as i=val 100 int get_i() {return this->i;} // same as return i};int main(){ c1 o; o.load_i(100); cout<<o.get_i(); return 0;} ‫وائل قصاص‬ 91
  92. 92. Operator Overloading C++ incorporates the option to use language standard operators between classes and between fundamental types. For example: int a, b, c; a = b + c; is valid, since the different variables of the addition are all fundamental types. While, the following operation is incorrect.struct { char product [50]; float price; } a, b, c; a = b + c; ‫وائل قصاص‬ 92
  93. 93.  The assignation of a class (or struct) to another one of the same type is allowed (default copy constructor). But addition operation in principle is not valid between non-fundamental types. C++ has the ability to overload operators. Objects derived from composed types such as the previous one can accept operators which would not be accepted otherwise, and we can even modify the effect of operators. Here is a list of all the operators that can be overloaded: + - * / = < > += -= *= /= << >> <<= >>= == != <= >= ++ -- % & ^ ! | ~ &= ^= |= && || %= [] () new delete
  94. 94. To overload an operator we only need to write a classmember function whose name is operator followed bythe operator sign that we want to overload, following thisprototype:type operator sign (parameters);Here you have an example that includes the operator +. We are going to sum the bi-dimensional vectors a(3,1) and b(1,2). The addition of two bi- dimensional vectors is an operation as simple as adding the two x coordinates to obtain the resulting x coordinate and adding the two y coordinates to obtain the resulting y. In this case the result will be (3+1,1+2) = (4,3).
  95. 95. #include <iostream.h>class CVector { public: int x,y; CVector () { }; CVector (int,int); CVector operator + (CVector); };CVector::CVector (int a, int b) { x = a; y = b;}CVector CVector::operator+ (CVector param) { CVector temp; 4,3 temp.x = x + param.x; temp.y = y + param.y; return (temp);}void main () { CVector a (3,1); CVector b (1,2); CVector c; c = a + b; cout << c.x << "," << c.y;} ‫وائل قصاص‬ 95
  96. 96. The function operator+ of class CVector is the one that is in charge of overloading the arithmetic operator +. This one can be called by any of these two ways: c = a + b; c = a.operator+ (b); Notice also that we have included the empty constructor (without parameters) and defined it with a no-op block of instructions: CVector () { };this is necessary, since there already exists another constructor, CVector (int, int);so none of the default constructors will exist in CVector if we do not explicitly declare one as we have done. Otherwise the declaration CVector c; included in main() would not be valid. Therefore, a more advisable declaration would have been something similar to this: CVector () { x=0; y=0; };
  97. 97.  As well as a class includes by default an empty and a copy constructor, it also includes a default definition for the assignation operator (=) between two classes of the same type. This copies the whole content of the non-static data members of the parameter object (the one at the right side of the sign) to the one at the left side. Of course, you can redefine it to any other functionality that you want for this operator, like for example, copy only certain class members. Although the prototype of a function operator+ can seem obvious since it takes the right side of the operator as the parameter for the function operator+ of the left side object, other operators are not so clear. Here you have a table with a summary on how the different operator functions must be declared (replace @ by the operator in each case):
  98. 98. where a is an object of class A, b is an object of class B and cis an object of class C.
  99. 99.  You can see in this panel that there are two ways to overload some class operators: as member function and as global function. Its use is indistinct; considering that functions that are not members of a class cannot access the private or protected members of the class unless the global function is friend of the class.
  100. 100. Operator Overloading Using Member Functionsclass myClass { void myClass::show() { int x, y, z; cout<<x<<“, “;public: cout<<y<<“, “; myClass() {x=y=z=0;} myClass(int i, int j, int k){x=i; cout<<z<<“n “; } y=j; z=k;} void main() { myClass operator+(myClass t); myClass a(1,2,3), b(10,10,10), c; myClass operator=(myClass t); void show();}; a.show();myClass myClass::operator+ b.show(); (myClass t) {myClass temp; c=a+b; temp.x=x+t.x; c.show(); temp.y=y+t.y; temp.z=z+t.z; c=a+b+c; return temp; } c.show();myClass c=b=a; myClass::operator=(myClass t) { c.show(); The Output is: x=t.x; b.show(); } 1,2,3 y=t.y; 10,10,10 z=t.z; 11,12,13 return *this;} 22,24,26 1,2,3 1,2,3
  101. 101. when a binary operator is overloaded using a member function, only one argument is explicitly passed to it. The other argument is implicitly passed using "this" pointer. Thus, in the line temp.x=x+t.x;The x refers to this->x, which is the x associated with the object that invokes the operator function. In all cases it is the object on the left side of an operation that causes the call to the operator function. The object on the right side is passed to the function.when you use a member function, no parameters are used when overloading a unary operator and only one parameter is required when overloading a binary operator.
  102. 102. Operator+() returns an object of type myClass. Although the function could have returned any valid C++ type, the fact that it returns a myClass object allows the + operator to be used in compound expressions, such as a+b+c. Here, a+b generates a result that is of type myClass. This value can then be added to c.The operator=() function is called by the object that occurs on the left side of the assignment, it is this object that is modified by the assignment operation.The return value of an overloaded assignment operator is the object on the left, after the assignment has been made.
  103. 103. Using Member Functions to Overload Unary Operators When a unary operator (i.e. ++ , --) is overloaded by means of a member function, no object is explicitly passed to the operator function. Instead, the operation is performed on the object that generates the call to the function through the implicitly passed this pointer.
  104. 104. #include <iostream.h>#include <stdlib.h>class myClass { void main() { int x, y, z; myClass a(1,2,3), b(10,10,10), c;public: a.show(); b.show(); myClass() {x=y=z=0;} c=a+b; myClass(int i, int j, int k){x=i; y=j; z=k;} c.show(); myClass operator+(myClass t); myClass operator++(); c=a+b+c; c.show(); void show();}; c=b=a; c.show();myClass myClass::operator++() b.show();{ ++x; ++c; ++y; c.show();} ++z; return *this;}myClass myClass::operator+(myClass t) { myClass temp; temp.x=x+t.x; 1, 2, 3 temp.y=y+t.y; 10, 10, 10 temp.z=z+t.z; return temp;} 11, 12, 13void myClass::show() { 22, 24, 26 cout<<x<<", "; 1, 2, 3 cout<<y<<", "; 1, 2, 3 cout<<z<<"n ";} 2, 3, 4 ‫وائل قصاص‬ 104
  105. 105.  operator++() increments each coordinate in the object and returns the modified object. The ++ and -- have both a prefix and a postfix form. In the preceding program, the operator++() function defines the prefix form of ++ relative to the three_d class. It is possible to overload the postfix form. The post operator will call the parameterized function, while the prefix will always call the non-parameterized function. The prototype for the postfix form of the ++ operator relative to the three_d class is shown here: three_d three_d::operator++(int notused); The parameter not used is not used by the function, and should be ignored. This parameter is simply a way for the compiler to distinguish between the prefix and postfix forms of the increment and decrement operators.
  106. 106. class three_d { three_d three_d::operator++() int x, y, z;public: { ++x; ++y; ++z; three_d() {x=y=z=0;} return *this;} three_d(int i, int j, int k){x=i; y=j; z=k;} three_d three_d::operator++(int notused) three_d operator+(three_d op2); { three_d temp=*this; three_d operator=(three_d op2); x++; y++; z++; three_d operator++(); return temp;} three_d operator++(int notused); // postfix void three_d::show() { void show(); }; cout<<x<<", ";three_d three_d::operator+(three_d op2) cout<<y<<", ";{ three_d temp; cout<<z<<"n ";} temp.x=x+op2.x; void main() temp.y=y+op2.y; { three_d a(1,2,3), b(10,10,10), c; temp.z=z+op2.z; 1, 2, 3 a.show(); b.show(); c=a+b; c.show(); return temp; } c=a+b+c; c.show(); c=b=a; c.show();three_d three_d::operator=(three_d op2) 10, 10, 10 b.show(); ++c;{ x=op2.x; 11, 12, 13 c.show(); y=op2.y; z=op2.z; 22, 24, 26 c++; c.show(); a=++c; a.show(); c.show(); return *this;} 1, 2, 3 a=c++; a.show(); c.show(); } 1, 2, 3 2, 3, 4 3, 4, 5 4, 5, 6 4, 5, 6 4, 5, 6 5, 6, 7
  107. 107. Overloading a relational operator such as == or <, is a straightforward process. overloaded operator function usually returns an object of the class for which it is overloaded. However, an overloaded relational operator typically returns a true or false value. To show how an overloaded relational operator can be implemented, the following function overloads the "==".int three_d::operator==(three_d t) { if ((x==t.x) && (y==t.y) && (z==t.z)) return 1; else return 0;}
  108. 108. class RelationalOver { int x, y, z;public: RelationalOver() {x=y=z=0;} RelationalOver(int i, int j, int k){x=i; y=j; z=k;} int operator==(RelationalOver op2); };int RelationalOver::operator==(RelationalOver t) { if ((x==t.x) && (y==t.y) && (z==t.z)) return 1; else return 0;}void main(){RelationalOver a(10,10,10), b(10,10,10);if (a==b)cout<<"The two objects are equal";elsecout<<"The two objects are not equal";}
  109. 109. Friend Operator Functions  The only operators that cannot be overloaded using friend functions are =,(),and ->.  Friend functions do not have a this pointer.  When a friend is used to overload an operator, both operands are passed explicitly if a binary operator is overloaded. If a unary operator is overloaded then a single operand is passed.  In The next program, a friend is used instead of a member function to overload the + operation. ‫وائل قصاص‬ 109
  110. 110. Friend OperatorFunctions  There is one situation in which you must use a friend function.  A pointer to the object that invokes a member operator function is passed in this. In the case of a binary operator, the object on the left invokes the function. This is fine, provided that the object on the left defines the specified operation. Assuming some object called O, which has assignment and addition defined for it, then this is perfectly valid statement: O = O + 10; //will work While; O = 10 + O; //won’t work  The problem with the above statement is that the object on the left side of the + operator is an integer, a built-in type for which no operation involving an integer and an object of O’s type is defined. Solution:  The problem of having a built-in type on the left side of an operation can be eliminated if the + is overloaded using two friend functions. In this case, the operator function is explicitly passed both arguments, and it is invoked like any other overloaded function, based upon the types of its argument.
  111. 111. class CL { //this handles int + ob.public: CL operator+(int i, CL ob){ int count; CL operator=(CL obj); CL temp; friend CL operator+(CL ob, int i); temp.count=ob.count+i; friend CL operator+(int i, CL ob); return temp;}; }CL CL::operator=(CL obj) { main() { count = obj.count; CL o; return *this; o.count=10;} cout<<o.count<<“ “;//outputs//this handles ob + int. 10CL operator+(CL ob, int i){ o=10+ o;// adds object to CL temp; integer. temp.count=ob.count+i; return temp; cout<<o.count<<“ “;//outputs} 20 o=o+12;// adds integer to object. cout<<o.count; // outputs 32 return o; } ‫وائل قصاص‬ 111
  112. 112. Using a Friend to Overload a UnaryOperator  In overloaded unary operator using member function, Every member function has an implicit argument, a pointer to the object that invokes it, which is referenced inside the member function by the keyword this.  Unlike member functions, a friend function does not receive a this pointer. And therefore cannot reference the object that invoked it. Instead, a friend operator function is passed its operand explicitly. For this reason, trying to create a friend operator++() function as shown here will not work. //This will not work three_d operator++(three_d op1) { op1.x++; This function will not work because only a op1.y++; op1.z++; copy of the object that activated the call to return op1; operator++() is passed to the function in } parameter op1. Thus, the changes inside will not effect the calling object ‫وائل قصاص‬ 112
  113. 113.  Using a friend function when overloading a unary ++ or -- requires that the object be passed to the function as a reference parameter. In this way the function can modify parameter the object. When a friend is used for overloading the increment or decrement operators, the prefix form takes one parameter. The postfix form takes two parameters. The second is an integer, which is not used. ‫وائل قصاص‬ 113
  114. 114. class three_d { int x, y, z;public: three_d() {x=y=z=0;} three_d(int i, int j, int k){x=i; y=j; z=k;} friend three_d operator+(three_d op1, three_d op2); three_d operator=(three_d op2); friend three_d operator++(three_d &op1); // prefix friend three_d operator++(three_d &op1 , int notused); void show();};three_d operator+(three_d op1 , three_d op2){ three_d temp; temp.x=op1.x+op2.x; temp.y=op1.y+op2.y; temp.z=op1.z+op2.z; return temp; } ‫وائل قصاص‬ 114
  115. 115. three_d three_d::operator=(three_d //overload the postfix version op2) three_d operator++(three_d &op1,{ int notused) x=op2.x; { y=op2.y; three_d temp=op1; op1.x++; z=op2.z; op1.y++; return *this; op1.z++;} return temp; }three_d operator++(three_d &op1){ void three_d::show() { op1.x++; cout<<x<<“, “; op1.y++; cout<<y<<“, “; op1.z++; cout<<z<<“n “; return op1; }}
  116. 116. main() a.show();{ c.show();three_d a(1,2,3), a=c++; b(10,10,10), c; a.show();a.show(); c.show();b.show(); return 0;c=a+b; }c.show();c=a+b+c;c.show();c=b=a;c.show();b.show();++c; // prefix incrementc.show();c++;//postfix incrementc.show();a=++c; ‫وائل قصاص‬ 116
  117. 117. Overloading [ ] The last operator we will overload is the [] array subscripting operator. In C++, the [] is considered a binary operator when it is overloaded. The [] can only be overloaded relative to a class, and only by a member function. Therefore, the general form of a member operator[ ]() function is: type class-name::operator[](int index) { // …… } Technically, the parameter does not have to be of type int, but operator[]() functions are typically used to provide array subscripting, so an integer value is generally used. ‫وائل قصاص‬ 117
  118. 118.  Given an object called O, this expression O[3]Translates into this call to the operator[]() function: operator[](3) That is, the value of the expression within the subscripting operator is passed to the operator[]() function explicitly. The this pointer will point to O, the object that generated the call. In the following program , atype declares an array of three integers. Its constructor function initialize each member of the array. The overloaded operator[]() function returns the value of the element specified by its parameter. ‫وائل قصاص‬ 118
  119. 119. #include <iostream>using namespace std;const int SIZE=3;class atype { int a[SIZE];public: atype() { register int i; for(i=0; i<SIZE;i++) a[i] = i; } int operator[](int i) {return i;}};int main(){ atype ob; cout<<ob[2]; // display 2 return 0;} ‫وائل قصاص‬ 119
  120. 120.  In the previous slide, the initialization of the array a by the constructor. It is possible to design the operator[]() function in such a way that the [] can be used on both the left and right sides of an assignment statement. To do this, simply specify that the return value of operator[]() be a reference.const int SIZE=3;class atype { int a[SIZE];public: atype() { register int i; for(i=0; i<SIZE;i++) a[i] = i; } int &operator[](int i) {return a[i];}};void main(){ atype ob; cout<<ob[2]; // display 2 cout<<“ “; ob[2]=25; // [] on left of = cout<<ob[2]; // now display 25}
  121. 121.  (in the previous program) Because operator[]() now returns a reference to the array element indexed by i, it can now be used on the left side of an assignment statement to modify an element of the array. One advantage of being able to overload the [] operator is that it provides a means of implementing safe array indexing. As you know, in C++, it is possible to overrun an array boundary at run time without generating a run- time error message. However, if you create a class that contains the array, and allow access to that array only through the overloaded [] subscripting operator, then you can intercept an out-of-range index. For example, the program shown next adds a range check to the preceding program, and proves that it works. ‫وائل قصاص‬ 121
  122. 122. #include <iostream.h> main()#include <stdlib.h> {const int SIZE=3;class atype { atype ob; int a[SIZE]; cout<<ob[2]; // display 2public: cout<<“ “; atype() { ob[2]=25; // [] on left of = register int i; for(i=0; i<SIZE;i++) a[i] = i; cout<<ob[2]; // display 25 } ob[3] = 44; // generates int &operator[](int i); //runtime}; error, 3// provide range checking for atype //out=of-rangeint &atype::operator[](int i) { return 0; if(i<0 || i>SIZE-1) { } cout<<“nindex value of “; In this program, when the cout<<i<<“ is out-of- statement ob[3]=44; range.n”; executes, the boundary exit(1); error is intercepted by } operator[](), and thereturn a[i]; program is terminated} befor any damage can be done. ‫وائل قصاص‬ 122
  123. 123.  In order to derive a class from another, we must use the operator: (colon) in the declaration of the derived class in the following way:class derived_class_name: public base_class_name; where derived_class_name is the name of the derived class and base_class_name is the name of the class on which it is based. public may be replaced by any of the other access specifiers protected or private, and describes the access for the inherited membersInheritance ‫وائل قصاص‬ 123
  124. 124. #include <iostream.h>class CPolygon { protected: int width, height; public: void set_values (int a, int b){ width=a; height=b;} };class CRectangle: public CPolygon {public: 20 int area (void) { return (width * height); } }; 10class CTriangle: public CPolygon { public: int area (void) { return (width * height / 2); } };void main () { CRectangle rect; CTriangle trgl; rect.set_values (4,5); trgl.set_values (4,5); cout << rect.area() << endl; cout << trgl.area() << endl; } ‫وائل قصاص‬ 124
  125. 125.  Objects of classes CRectangle and CTriangle each contain members of CPolygon, that are: width, height and set_values(). The protected specifier is similar to private, its only difference occurs when deriving classes. When we derive a class, protected members of the base class can be used by other members of the derived class. Nevertheless, private member cannot. Since we wanted width and height to have the ability to be manipulated by members of the derived classes CRectangle and CTriangle and not only by members of CPolygon, we have used protected access instead of private. ‫وائل قصاص‬ 125
  126. 126.  We can summarize the different access types according to whom can access them in the following way: Access Public protected private members of the yes yes yes same class members of yes yes no derived classes not-members yes no no 126 ‫وائل قصاص‬
  127. 127.  where "not-members" represent any reference from outside the class, such as from main(), from another class or from any function, either global or local. In above example, the members inherited by CRectangle and CTriangle follow with the same access permission as in the base class CPolygon:CPolygon::width // protected accessCRectangle::width // protected accessCPolygon::set_values() // public accessCRectangle::set_values() // public accessThis is because we have derived a class from the other as public, remember: class CRectangle: public CPolygon;
  128. 128.  This public keyword represents the minimum level of protection that the inherited members of the base class (CPolygon) must acquire in the new class (CRectangle). The minimum access level for the inherited members can be changed by specifying protected or private instead of public. For example, daughter is a class derived from mother that we defined thus:class daughter: protected mother; This would establish protected as the minimum access level for the members of daughter that it inherited from mother. That is, all members that were public in mother would become protected in daughter, that would be the minimum level at which they can be inherited. Of course, this would not restrict that daughter could have its own public members. The minimum level would only be established for the inherited members of mother.
  129. 129.  The most common use of an inheritance level different from public is private that serves to completely encapsulate the base class, since, in that case, nobody except its own class will be able to access the members of the base class from which it is derived. Anyway, in most cases classes are derived as public. If no access level is explicitly written, private is assumed for classes created with the class keyword and public for those created with struct.
  130. 130.  Granting Access: When a base class is inherited as private, all members of that class (public or protected) become private members of the derived class. However, in certain circumstances, you may want to restore one or more inherited members to their original access specification. For example, you might want to grant certain public members of the base class public status in the derived class even though the base class is inherited as private. To do this, you must use an access declaration within the derived class. An access declaration takes this general form: base-class::member; ‫وائل قصاص‬ 130
  131. 131. class base {public: int j; // public in base}; // Inherit base as privateclass derived: private base {public: base::j; // make j public again // …….};You can use an access declaration to restore the access rights of public and protected members. However, you cannot use an access declaration to raise or lower a member’s access status. For example, a member declared as private within a base class cannot be made public by a derived class. (allowing this would destroy encapsulation!).
  132. 132. class base { int i; // private to base public: int j, k; void seti(int x) {i=x;} void main() int geti() {return i;}}; { derived ob;class derived: private base { //ob.i=10; illegal because /* The next three statements override ob.j=20; /* legal j is made public*/ base’s inheritance as private and //ob.k=30;/*illegal k is private */ restore j, seti() and geti() to public ob.a=40;/* legal a is public*/ access. */ ob.seti(10); public: cout<<ob.geti()<<“ “; base::j; // make j public again cout<<ob.j<<“ “<<ob.a; base::seti; // make seti() public } base::geti; // make geti() public // base::i; //illegal, you cannot elevate access int a; }; // public ‫وائل قصاص‬ 132
  133. 133. What is inherited from the base class? In principle every member of a base class is inherited by a derived class except:Constructor and destructoroperator=() memberfriends Although the constructor and destructor of the base class are not inherited, the default constructor (i.e. constructor with no parameters) and the destructor of the base class are always called when a new object of a derived class is created or destroyed. If the base class has no default constructor or you want that an overloaded constructor is called when a new derived object is created, you can specify it in each constructor definition of the derived class:derived_class_name (parameters): base_class_name (parameters) {}
  134. 134. // constructors and derivated classes#include <iostream.h>class mother { public: mother () { mother: no cout << "mother: no parametersn"; } parameters mother (int a) { daughter: int cout << "mother: int parametern"; } }; parameter mother: intclass daughter : public mother { parameter public: son: int parameter daughter (int a) { cout << "daughter: int parameternn"; } };class son : public mother { public: son (int a) : mother (a) { cout << "son: intparameternn"; } };void main () { daughter cynthia (1); son daniel(1);} ‫وائل قصاص‬ 134
  135. 135.  Observe the difference between which mothers constructor is called when a new daughter object is created and which when it is a son object. The difference is because the constructor declaration of daughter and son:daughter (int a) // nothing specified: call default constructorson (int a) : mother (a) // constructor specified: call this one ‫وائل قصاص‬ 135
  136. 136.  In C++ it is perfectly possible that a class inherits fields and methods from more than one class simply by separating the different base classes with commas in the declaration of the derived class. For example, if we had a specific class to print on screen (COutput) and we wanted that our classes CRectangle and CTriangle also inherit its members in addition to those of CPolygon we could write:class CRectangle: public CPolygon, public COutput {}class CTriangle: public CPolygon, public COutput { }Multiple inheritance ‫وائل قصاص‬ 136
  137. 137. #include <iostream.h>class CPolygon { protected: int width, height; public: void set_values (int a, int b) { width=a; height=b;}}; void main () { CRectangle rect;class COutput { CTriangle trgl; public: rect.set_values (4,5); void output (int i); }; trgl.set_values (4,5);void COutput::output (int i){ cout << i << endl; } rect.output (rect.area()); Trgl.output (trgl.area());}class CRectangle: public CPolygon, public COutput { public: int area (void) { return (width * height); } };class CTriangle: public CPolygon, public COutput { 20 public: 10 int area (void) { return (width * height / 2); }}; ‫وائل قصاص‬ 137
  138. 138.  For a suitable understanding of this section you should clearly know how to use pointers and inheritance between classes. Polymorphism in the context of object-oriented programming, is the ability of one type, A, to appear as and be used like another type, B. Type A somehow derives from type B, or type C implements an interface that represents type B.Polymorphism ‫وائل قصاص‬ 138
  139. 139. Pointers to base class One of the greater advantages of deriving classes is that a pointer to a derived class is type-compatible with a pointer to its base class. ‫وائل قصاص‬ 139
  140. 140. // pointers to base class#include <iostream.h> int main () {class CPolygon { CRectangle rect; protected: CTriangle trgl; int width, height; public: CPolygon * p1 = &rect; void set_values (int a, int b) { CPolygon * p2 = &trgl; width=a; height=b; } }; p1->set_values (4,5);class CRectangle: public CPolygon { p2->set_values (4,5); public: int area (void){ return (width * height); } }; cout << rect.area() << endl; cout << trgl.area() << endl;class CTriangle: public CPolygon { return 0;} public: int area (void){ return (width * height / 2); } }; 20 10 ‫وائل قصاص‬ Code 140
  141. 141.  The function main creates two pointers that point to objects of class CPolygon, that are *p1 and *p2. These are assigned to the addresses of rect and trgl, and because they are objects of classes derived from CPolygon they are valid assignations. The only limitation of using *p1 and *p2 instead of rect and trgl is that both *p1 and *p2 are of type CPolygon* and therefore we can only refer to the members that CRectangle and CTriangle inherit from CPolygon. For that reason when calling the area() members we have not been able to use the pointers *p1 and *p2. To make it possible for the pointers to class CPolygon to admit area () as a valid member, this should also have been declared in the base class and not only in its derived ones.
  142. 142.  In order to declare an element of a class which we are going to redefine in derived classes we must precede it with the keyword virtual so that the use of pointers to objects of that class can be suitable.Virtual members ‫وائل قصاص‬ 142
  143. 143. #include <iostream.h> int main () {class CPolygon { CRectangle rect; protected: CTriangle trgl; int width, height; CPolygon poly; public: CPolygon * p1 = &rect; void set_values (int a, int b) { width=a; height=b; } CPolygon *p2=&trgl; virtual int area (void) { CPolygon * p3 = &poly; return (0); } }; p1->set_values(4,5); p2->set_values(4,5);class CRectangle: public CPolygon { p3->set_values (4,5); public: cout << p1->area() << endl; int area (void){ cout << p2->area() << endl; return (width * height); } }; cout << p3->area() << endl;}class CTriangle: public CPolygon { public: int area (void){ 20 return (width * height / 2); } }; 10 0 ‫وائل قصاص‬ 143
  144. 144.  The three classes (CPolygon, CRectangle and CTriangle) have the same members: width, height, set_values() and area(). area() has been defined as virtual because it is later redefined in derived classes. You can verify if you want that if you remove this word (virtual) from the code and then you execute the program the result will be 0 for the three polygons instead of 20,10,0. That is because instead of calling the corresponding area() function for each object (CRectangle::area(), CTriangle::area() and CPolygon::area(), respectively), CPolygon::area() will be called for all of them since the calls are via a pointer to CPolygon. Therefore, what the word virtual does is to allow a member of a derived class with the same name as one in the base class be suitably called when a pointer to it is used Note that in spite of its virtuality we have also been able to declare an object of type CPolygon and to call its area() function, that always returns 0 as the result.
  145. 145. Abstract base classes Abstract classes are similar to the class CPolygon of our previous example. The only difference is that in our previous example we have defined a valid area() function for objects that were of class CPolygon (like object poly), whereas in an abstract base class we could have simply left without defining this function by appending = 0 to the function declaration. The class CPolygon could have been thus:// abstract class CPolygonclassCPolygon { protected: int width, height; public: void set_values(int a, int b){width=a; height=b;} virtual int area (void) =0; };
  146. 146.  This type of function is called a pure virtual function, and all classes that contain a pure virtual function are considered abstract base classes. The greatest difference of an abstract base class is that instances (objects) of it cannot be created, but we can create pointers to them. Therefore a declaration likes:CPolygon poly; // incorrectCPolygon * ppoly1; //correctThis is because the pure virtual function that it includes is not defined and it is impossible to create an object if it does not have all its members defined. A pointer that points to an object of a derived class where this function has been defined is perfectly valid.
  147. 147. #include <iostream.h>class CPolygon { int main () { protected: CRectangle rect; int width, height; CTriangle trgl; public: CPolygon * ppoly1 = &rect; void set_values (int a, int b) { width=a; CPolygon * ppoly2 = &trgl; height=b; } virtual int area (void) =0; ppoly1->set_values (4,5); }; ppoly2->set_values (4,5); cout << ppoly1->area() << endl;class CRectangle: public CPolygon { cout << ppoly2->area() << endl; public: int area (void){ return 0;} return (width * height); } };class CTriangle: public CPolygon { public: 20 int area (void){ 10 return (width * height / 2); } };
  148. 148.  If you review the program you will notice that we can refer to objects of different classes using a unique type of pointer (CPolygon*). This can be tremendously useful. Imagine, now we can create a function member of CPolygon that is able to print on screen the result of the area() function independently of what the derived classes are. ‫وائل قصاص‬ 148
  149. 149. #include <iostream.h>class Polygon { protected: int width, height; public: void set_values (int a, int b){ width=a; height=b; } virtual int area (void) =0; void printarea (void){ cout << this->area() << endl; } };class Rectangle: public Polygon { public: int area (void){ return (width * height); } };class Triangle: public Polygon { public: int area (void){ return (width * height / 2); } };int main () { Rectangle rect; Triangle trgl; Polygon * p1 = &rect; Polygon * p2 = &trgl; p1->set_values (4,5); p2->set_values (4,5); p1->printarea(); p2->printarea(); return 0;} ‫وائل قصاص‬ 149
  150. 150.  Remember that this represents a pointer to the object whose code is being executed. Abstract classes and virtual members grant to C++ the polymorphic characteristics that make object-oriented programming such a useful instrument. Of course we have seen the simplest way to use these features, but imagine these features applied to arrays of objects or objects assigned through dynamic memory. ‫وائل قصاص‬ 150
  151. 151. Early Versus Late Binding Early binding and late binding. These terms refer to events that occur at compile time and events that occur at run time. Early binding means that a function call is resolved at compile time. All information necessary for determining which function will be called is known when the program is compiled. (i.e. standard function calls, overloaded function calls, and overloaded operator function calls). The principle advantage to early binding is efficiency-it is faster, and it often requires less memory. Its disadvantage is lack of flexibility. ‫وائل قصاص‬ 151