1 / 15

Inheritance mechanism

Inheritance mechanism. class Person { public: void f( void ){ cout &lt; ”Person<br>”; } }; class Employee { public: void f( void ){ cout ”Employee<br>”; } } Person p1; p1.f(); Person *p2 = new Employee; p2-&gt;f(); Employee p3; void g( Person p ){ p.f(); } g( p3 );. What is printed?.

abrial
Download Presentation

Inheritance mechanism

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Inheritance mechanism class Person { public: void f( void ){ cout < ”Person\n”; } }; class Employee { public: void f( void ){ cout ”Employee\n”; } } Person p1; p1.f(); Person *p2 = new Employee; p2->f(); Employee p3; void g( Person p ){ p.f(); } g( p3 ); What is printed? C++ by default uses the methods according to the type is knows, not of the actual object (static binding).

  2. Printing a person class Person { public: Person (const char * name);   ~Person (void); // I/O friend. friend ostream & operator<<( ostream & os, const Person & p ); protected: char * name; }; class Student : public Person { public: Student (const char * n, const float * m, int nr);   ~Student (void); // I/O friend. friend ostream & operator<<( ostream & os, const Student & s ); private: int nrMarks; float * marks; };

  3. Printing a person int main (void){ Person m ("Marten Wensink"); float cijfers [5] = {6.4f, 7.5f, 4.2f}; Student s ("D.E.Student", cijfers, 3); cout << m << '\n' << s << '\n' << endl; cout << "********* Testing references. ********\n"; Person & r0 = m; Person & r1 = s; // Display using references: cout << r0 << endl; cout << r1 << endl << endl; cout << "********* Testing pointers. **********\n"; Person * p[2]; p[0] = new Person ("Marten Wensink"); p[1] = new Student ("D.E.Student", cijfers, 3); // Display using pointers: for (int i = 0; i < 2; i++){ cout << *p[i] << endl; } cout << endl; cout << "*** Testing destructors for array. ***\n"; for (i = 0; i < 2; i++){ delete p[i]; cout << endl; } cout << "Finalising program...\n"; return 0; } Person: Marten Wensink Student: D.E.Student Cijfers: 6.4 7.5 4.2 ************ Testing references. *********** Person: Marten Wensink Person: D.E.Student ************* Testing pointers. ************ Person: Marten Wensink Person: D.E.Student ****** Testing destructors for array. ****** Calling destructor for Person. Calling destructor for Person. Finalising program... Calling destructor for Student. Calling destructor for Person. Calling destructor for Person. 3 destructors called. For which objects?

  4. Dynamic binding • At run time, check to which class the actual object belongs, and use the method from that actual class. • Does what you expect. • Is somewhat slower than the default static binding. class Person { public: Person (const char * name);   virtual ~Person (void); friend ostream & operator<<( ostream & os, const Person & p ); protected: char * name; }; This friendly operator<< is not a member function, so it can not be virtual 

  5. Delegate printing to a member function class Person { public: // Destructor (should always be virtual !!). virtual ~Person (void); // I/O friend. friend ostream & operator<< (ostream & os, const Person & p){ p.printInfo(os); return os; } private: // Private virtual function. virtual void printInfo (ostream & os) const; }; • ”virtual-ness” is inherited: • No need to re-specify it in a derived class • You can’t even do that: it must be mentioned in the highest class!

  6. Abstract classes You can postpone the body of a member function by specifying it as =0 : class Vehicle { public: . . . private: // Pure virtual operation virtual void printInfo (ostream & os) const = 0; }; Such a function is called pure virtual. A class with at least one such function is called abstract. C++ has no interface classes, but a class with all functions pure virtual has the same effect.

  7. Abstract classes You can postpone the body of a member function by specifying it as =0 : class Vehicle { . . . private: // Pure virtual operation virtual void printInfo (ostream & os) const = 0; }; Such a function is called pure virtual. A class with at least one such function is called abstract. An abstract class can not be instantiated. C++ has no interface classes, but a class with all functions pure virtual has the same effect.

  8. Vehicles class hierargy Note: operator=, copy constructor, etc. not show!

  9. Vehicle class Vehicle { public: // Virtual destructor virtual ~Vehicle (void) { } // I/O-friend friend ostream & operator<<( ostream & os, const Vehicle & v ){ v.printInfo (os); return os; } private: // Pure virtual operation virtual void printInfo (ostream & os) const = 0; }; Vehicle is virtual: it is an abstract entity, you can’t buy just a vehicle.

  10. Bike class Bike : public Vehicle { // No extra operations. // No data. }; Bike does not define the printInfo, so it is also virtual.

  11. RaceBike class RaceBike : public Bike { public: // Constructor. RaceBike (int n) : numGears (n) { } protected: int numGears; private: void printInfo (ostream & os) const; }; void RaceBike::printInfo ( ostream & os ) const { os << "A race bike with " << numGears << " gears"; } printInfo is implemented, so RaceBike is a concrete claass.

  12. MotorVehicle class MotorVehicle : public Vehicle { public: MotorVehicle (const char * num ){ regNum = new string (num); } ~MotorVehicle (void){ cout << "Destruction of " << *regNum << endl; delete regNum; } const string & number (void) const{ return *regNum; } protected: string * regNum; private: void printInfo (ostream & os) const; }; printInfo is implemented, so MotorVehicle is a concrete class. void MotorVehicle::printInfo (ostream & os) const { os << "A motor vehicle with reg.no: " << number(); }

  13. PrivateCar class PrivateCar : public MotorVehicle { public: // Constructor. PrivateCar( const char * num, int n ): MotorVehicle (num), numSeats (n) {} protected: int numSeats; private: void printInfo (ostream & os) const; }; printInfo is implemented, so PrivateCar is a concrete class. (and if it was not?) void PrivateCar::printInfo (ostream & os) const { os << "A private car with reg.no: " << number() << " and " << numSeats << " seats"; } Bad practice. How should this be done?

  14. Printing vehicles int main( void ){ MotorVehicle m ("MW-100"); cout << m << endl; Vehicle * pM = new MotorVehicle ("MW-101"); cout << *pM << endl; Vehicle & vr = m; cout << vr << endl << endl; PrivateCar c ("MW-200", 4); cout << c << endl; Vehicle * pC = new PrivateCar ("MW-201", 5); cout << *pC << endl; MotorVehicle * pPC = new PrivateCar ("MW-202", 6); cout << *pPC << endl << endl; RaceBike rb (10); cout << rb << endl; Bike * pRB = new RaceBike (14); cout << *pRB << endl; Vehicle * pV = new RaceBike (16); cout << *pV << endl; cout << "\n********** Deleting objects. *******\n"; delete pM; delete pC; delete pPC; delete pRB; delete pV; cout << "\n******** Finalising program. *******\n"; } A motor vehicle with reg.no: MW-100 A motor vehicle with reg.no: MW-101 A motor vehicle with reg.no: MW-100 A private car with reg.no MW-200 and 4 seats A private car with reg.no MW-201 and 5 seats A private car with reg.no MW-202 and 6 seats A race bike with 10 gears A race bike with 14 gears A race bike with 16 gears ************* Deleting objects. ************ Destruction of MW-101 Destruction of MW-201 Destruction of MW-202 ************ Finalising program. *********** Destruction of MW-200 Destruction of MW-100 .

More Related