Presentation is loading. Please wait.

Presentation is loading. Please wait.

The C++ programming language

Similar presentations


Presentation on theme: "The C++ programming language"— Presentation transcript:

1 The C++ programming language
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./0. The C++ programming language Class hierarchy, inheritance, virtual functions Access levels of class members Function polymorphism along the inheritance chain Virtual member functions The problem of multiple inheritance

2 Access levels of class members
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./1. Access levels of class members The data members and member functions of a class have private access level by default that means they can only be referred directly in the member functions of the class. This character applying on data members and local functions - that required only by the class - realises the principle of data- and functionality hiding. The access of data members and functionality of class to achieve the possibility of latter modification of class is expedient through the functions that are in communication with the environment. Consequently the modification of class or objects that derived from it will not require the alteration of the interface of the class. Of course, in case of communicating interface functions the access from everywhere is desirable to make possible the communication among objects by function calls, messages. This goal can be fulfilled using public access specifier. In case of derived classes it is desirable to stop the hiding of private members of the base, ancestor class and to make possible to refer to them directly in the member functions of the derived classes. Such extension of accessibility can be get applying the protected access specifier in the base class.

3 Function polymorphism along the inheritance chain
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./2. Function polymorphism along the inheritance chain count names[ ] SetCount() GetCount() SetElement() GetElement() class instance List Let us inherit from the base class List the class Marks, that do has a new numbers[ ] vector to store the numerical form of marks and an Average() function for calculation of the average of them besides the inherited data members and member functions. In the inherited names[ ] vector the excellent, good, fair, weak and fail qualifiers of the marks will be stored. numbers[ ] NumbersFromMarks() SetElement() GetElement() Average() Marks repetitionNo[ ] SetElement() GetElement() Let us inherit from the class Marks the subclass MarksOfExam which do has a repetitionNo[ ] vector besides the inherited members. An element of this vector shows the number of the repetitions of exams that were needed to get the stored mark. MarksOfExam MOE2004 MOE2005

4 Department of Information Engineering INFORMATION TECHNOLOGY dr
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./3. It can be observed in the chain of inheritance that every class - List, Marks or MarksOfExam - has SetElement( ) and GetElement( ) functions. We would like if these functions have different functionality in the Mark class as they had in the List class. In the Mark class they have to handle the name of the mark (excellent) and the numerical form of the mark (5) at the same time. Similarly, it is expected of the functions of class MarksOfExam to handle the number of repetitions of the exams besides the name and numerical form of the mark. If the first examination was successful than the value of repetition is zero. The resolution is obvious: the new functions having the same name have to use different parameter signature and different function body: class List { … public: ... void SetElement(int i, char* nameIn) { strcpy(names[ i ], nameIn);} void GetElement(int i, char* nameOut ) { strcpy(nameOut, names[ i ] );} }; //continued

5 Department of Information Engineering INFORMATION TECHNOLOGY dr
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./4. class Marks : public List // Inherits everything from the class List. { protected: int* numbers; // This pointer will be used for allocating the vector by the constructor. public: Marks (int count0= 0); // Declaration of the constructor ~Marks( ); // Declaration of the destructor void SetElement(int i, int numberIn); // See the definition later void GetElement(int i, int& numberOut, char* nameOut ) {numberOut = numbers[ i ]; strcpy(nameOut, names[ i ] );} double Average( ); // See the definition later. }; class MarksOfExam : public Marks // Inherits everything from the class Marks. { private: int* repetitionNo; // 0,1, 2, 3 public: MarksOfExam (int count0 = 0 ); // Declaration of the constructor ~ MarksOfExam ( ); // Declaration of the destructor void SetElement(int i, int numberIn, int which) {repetitionNo[ i ]= which; Marks:: SetElement(i, numberIn);}; void GetElement(int i, int& numberOut, char* nameOut , int& which ) {Marks:: GetElement(i, numberOut, nameOut ); which = repetitionNo[ i ]; } }; //continued

6 MarksOfExam MOE2004 (200), MOE2005 (250); // MarksOfExam-type objects.
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./5. MarksOfExam MOE2004 (200), MOE2005 (250); // MarksOfExam-type objects. void main( ) { … // Here is the main program that uses the objects. } // Function definitions: … Marks :: Marks(int count0) : List(count0) { numbers = new int[count0]; for (int i =0; i < count0; i++) {numbers[ i ]= 5; strcpy(names[ i ], "excellent"); } } Marks :: ~ Marks( ) { delete[ ] numbers; } void Marks :: SetElement(int i, int numberIn) { char ss[5][10]= {"fail","weak","fear","good","excellent"}; numbers[ i ]= numberIn; strcpy(names[ i ], ss[numberIn -1]); }

7 MarksOfExam :: ~MarksOfExam ( ) { delete[ ] repetitionNo ; }
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./6. double Marks :: Average( ) { double sum= 0.0; for (int i =0; i < count; i++) sum += numbers[ i ]; return sum / count; } MarksOfExam :: MarksOfExam (int count0 ) : Marks(count0) { repetitionNo = new int[ count0 ]; for ( int i =0; i < count0 ; i++) repetitionNo[ i ]= 0; } MarksOfExam :: ~MarksOfExam ( ) { delete[ ] repetitionNo ; } Remark: the MarksOfExam MOE2004(200); object definition creates an object for storing the results of exams for 200 students. The constructor of the MarksOfExam class passes the count number 200 to the constructor of Marks class that gives it to the constructor of List class. The constructor of List allocates the space for names, initializes it, then pass the execution to constructor of Marks. That allocates the numbers vector, initializes that and writes in the excellent mark names into names vector. Than the constructor of MarksOfExam follows: allocates the repetitionNo vector and fills it up with zeros.

8 Virtual member functions
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./7. Virtual member functions count names[ ] ... Swap( int i, int j ) Compare(int i, int j ) Sorting() class instance List It would be advantageous if the List class would have a sorting function to sort the names into ABC. This would inherit to the Marks class but there we would like to sort into ascending order by numerical values of marks (1,2,3,4,5) instead of names (fail, weak,…). The names have to move together with the numbers of course. PROBLEM: the same names of functions and the same parameter signatures! numbers[ ] Swap(int i, int j ) Compare(int i, int j ) ... Marks repetitionNo[ ] Swap(int i, int j ) ... MarksOfExam Moreover we would like to sort the marks of exams by numbers too, but the repetition number values have to move together with names and numbers of marks when the changes of place are performed. MOE2004 MOE2005

9 Department of Information Engineering INFORMATION TECHNOLOGY dr
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./8. The problem is that the Sorting( ) function that is inherited to the Marks class and to the MarksOfExam class have to use one of the Swap(int i, int j ) functions that are not distinguishable by name or parameter signature. How can the Sorting( ) function select from them? Answer: the selection will be determined by the object that will have the Sorting() function connected to it in the function call. This will only be discovered during running of the program therefore such type of function association performed at running time is named dynamic, late binding. The functions having the same name and parameter signature can be distinguished easily using the :: scope operator. This type of identification that can be used in the program (and has effect in compilation time) is named early, static binding. Associating such a manner the Swap() function to one of the class in the definition of the Sorting() function the derived Sorting() function may fail. To prepare for selection at running time the first occurrence of the Swap() function in the inheriting chain has to have the virtual keyword. Why virtual (apparent, not true) the function? Suppose that the names of List class do not have to be sorted only the vectors of the derived Group, Marks and MarksOfExam classes. A virtual Swap(int i, int j) function without definition, full determination can be used at this time too to define the Sorting() function fully in the List class. A class having such truly virtual function may not have an instance.

10 Department of Information Engineering INFORMATION TECHNOLOGY dr
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./9. The C++ solution: ... class List { protected: int count; t_name * names; virtual void Swap(int i, int j ) // Swaps the names { t_name buff ; strcpy(buff, names[ i ]); strcpy(names[ i ], names[ j ]); strcpy(names[ j ], buff ); } virtual int Compare(int i, int j ) // Compares the names { return strcmp(names[ i ], names[ j ]); } public: … void Sorting(); // The definition that uses the Swap() and the // Compare() functions is given later. }; // Continued

11 Department of Information Engineering INFORMATION TECHNOLOGY dr
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./10. ... class Marks : public List { protected: int * numbers; void Swap(int i, int j ) {int buff ; buff= numbers[ i ]; numbers[ i ]= numbers[ j ]; numbers[ j ]= buff ; t_name buf; strcpy(buf, names[ i ]); strcpy(names[ i ], names[ j ]); strcpy(names[ j ], buf); } int Compare(int i, int j ) { if numbers[ i ]< numbers[ j ]) return -1; else if (numbers[ i ]== numbers[ j ]) return 0; else return 1; } }; // Continued

12 Department of Information Engineering INFORMATION TECHNOLOGY dr
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./11. ... class MarksOfExam : public Marks { private: int * repetitionNo; void Swap(int i, int j ) { Marks :: Swap( i, j ); int b= repetitionNo[ i ]; repetitionNo[ i ]= repetitionNo[ j ]; repetitionNo[ j ]= b; } List dwarfs(7); // Defining object variables. Marks marks(25); MarksOfExam MOE2004(200); void main( ) { … dwarfs.Sorting(); marks.Sorting(); MOE2004.Sorting(); ... } // Continued

13 Department of Information Engineering INFORMATION TECHNOLOGY dr
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./12. ... // The fully defined but virtual function-depending sorting function: void List :: Sorting() { if (count > 1) // If there are elements to be sorted. for (int i = 0; i < count -1; j++) for (int j = i+1; j < count; j++) if (Compare( i, j ) > 0) Swap( i , j ); // They will be substituted in runtime !! puts("\n Sorting is ready."); }

14 The problem of multiple inheritance
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./13. The problem of multiple inheritance count names[ ] SetCount() GetCount() SetElement() GetElement() List class instance The class List is inherited into class TestResults two times numbers[ ] NumbersFromMarks() SetElement() GetElement() Average() groupNo SetGroupNo() GetGroupNo() Group Marks subject date AmountOfFails() TestResults TestGK201 TestGK301

15 Department of Information Engineering INFORMATION TECHNOLOGY dr
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./14. In case of one of the multiple inheritance the members of List class are doubled in the TestResults class. This is desirable in case of names[ ] vector since the list of names of the group is in the names[ ] vector and the names of marks of the students of the group are in the other names[ ] vector that comes from the Marks class, but is disturbing in case of count data members because these store same values and the repetition is superfluous. Keep in your mind that virtual inheritance exists to avoid duplication of data members but in this situation the duplication seems to be more suitable. It will be shown later that difference of the two count data members can be avoided. ... class TestResults : public Group, public Marks // It has two ancestors. { private: char subject[30]; // What subject was tested char date[12]; // When the test was written. public: TestResults(int count0= 0, char* subject0= "Information Technology", char* date0= "3/28/2004"); // Declaration of the constructor ~ TestResults( ); // Declaration of the destructor int AmountOfFails( ); // Declaration of a member function. }; //Continued

16 Department of Information Engineering INFORMATION TECHNOLOGY dr
Department of Information Engineering INFORMATION TECHNOLOGY dr. László Dudás 29./15. ... TestResults TestGK201(28), TestGK301(33); void main( ) { … TestGK301. Marks :: Sorting( ); // The scope operator helps to choose TestGK301. Group :: Sorting( ); // from the functions having the same name. printf("Average= %5.1lf ", TestGK301.Average( ) ); // Unambiguous case } // The duplication of the count is no problem because the same values are transferred on the // two ways from the constructors: TestResults :: TestResults(int count0, char* subject0, char* date0) : Marks(count0), Group(count0) { strcpy(subject, subject0 ); strcpy(date, date0); TestResults :: ~ TestResults( ) { } // Definition of the destructor function. int TestResults :: AmountOfFails( ) { int k =0; for (int i =0; i <Marks::count; i++) if (numbers[ i ]==1) k++; return k; }


Download ppt "The C++ programming language"

Similar presentations


Ads by Google