190 likes | 393 Views
7. Inheritance and Polymorphism . Yan Shi CS/SE 2630 Lecture Notes. Modern Object-Oriented Concepts. Modern object-oriented (OO) languages provide 3 capabilities: encapsulation inheritance polymorphism which can improve the design, structure and reusability of code. Inheritance in C++.
E N D
7. Inheritance and Polymorphism Yan Shi CS/SE 2630 Lecture Notes
Modern Object-Oriented Concepts • Modern object-oriented (OO) languages provide 3 capabilities: • encapsulation • inheritance • polymorphism which can improve the design, structure and reusability of code.
Inheritance in C++ • Syntax: class X : public Y FuncChild( type x ) : FuncParent( x ) { } • Example: • class Manager: public Employee
public, protected and private • as access specifier of class members: • public: everyone who knows the class can access the member • protected: only the class itself and its children can access the member • private: no one but the class itself can access the member • as inheritance specifier: • public: everyone who knows the Base and Child also know the inheritance relation. • protected: only Child and its children knows the inheritance relation. • private: no one other than Child knows the inheritance relation. • We only use public inheritance in this course! • This guarantees all the public data and methods from the base class remain public in the derived class.
What is inherited? • In principle, a derived class inherits every member of a base class except: • its constructor and its destructor • its operator=() members • its friends • Although the constructors and destructors of the base class are not inherited themselves, its default constructor (i.e., its constructor with no parameters) and its destructor are always called when a new object of a derived class is created or destroyed. • What if the base class has no default constructor?
Member Initialization List • For class constructors only • can be used to overload constructors Manager::Manager(stringn, floatrate, boolisSalaried ) : Employee( n, rate ) { salaried = isSalaried; } • can be used to initialize data members in constructors Employee(stringn, floatrate ) : name(n), payRate(rate) {}
Multiple Inheritance • In C++ it is possible that a class inherits members from more than one class. class Son: public Mother, public Father; • However, it smells! • You will learn more details in later design classes. • See the example on the course page.
Polymorphism • polymorphismmeans that some code or operations or objects behave differently in different contexts. • How to decide? • static binding: at compilation time (overloading) • dynamic binding: at run time (virtual functions) • C++ uses virtual functions to implement dynamic binding. • when the term polymorphism is used with C++, it refers to using virtual functions
Base Class Pointer • We can assign a pointer to a derived class to a variable declared using the base class Employee * emp; emp = newManager( name, rate, true); cout << emp->Name() << " : $" << emp->Pay( hours ) << endl; • By default, it is the type of the pointer (i.e., Employee), not the type of the object it points to (i.e., possibly Manager) that determines which version will be called. • How to call Manager::Pay( hours )? • Make Employee::Pay( int hours ) virtual! virtualfloat Pay( floathoursWorked ) const;
Virtual Function • A member of a class that can be redefined in its derived classes is known as a virtual member. • precede its declaration with the keyword virtual • Once a method is declared as virtual, it is virtual in all derived classes too. • Destructors should always be virtual! (See example) • Constructors are nevervirtual! Why?
vtable • A virtual method/function/call table is to support run-time method binding. • contains pointers to virtual functions • Typically, the compiler creates a separate vtable for each class. • When an object is created, a pointer to this vtable, called the virtual table pointer, vpointer or VPTR, is added as a hidden member of this object. • For any class that contains a vtable, the compiler will also add "hidden" code to the constructor of that class to initialize the vpointers of its objects to the address of the corresponding vtable.
vtable example class C { public: virtual void f(); void g(); virtual void h(); }; class D : public C { public: void f(); void u(); virtual void v(); }; C cObj; D dObj; vtable for C: +0: C::f() // pointer +4: C::h() vtable for D: +0: D::f() // f is overloaded +4: C::h() // h is not +8: D::v()
Type Cast of Objects • Explicit conversion: Employee * emp; Manager * m = (Manager*)(emp); • Traditional explicit type-casting allows to convert any pointer into any other pointer type, independently of the types they point to. The subsequent call to member functions will produce either a run-time error or a unexpected result. • dynamic_cast <new_type> (expression) • reinterpret_cast<new_type> (expression) • static_cast<new_type> (expression) • const_cast<new_type> (expression)
static_cast • perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived. • can also be used to perform any other non-pointer conversion • ensures that at least the classes are compatible if the proper object is converted, but no safety check is performed during runtime to check if the object being converted is in fact a full object of the destination type. • it is up to the programmer to ensure that the conversion is safe. class CBase {}; class CDerived: public CBase {}; CBase* a = new CBase; CDerived* b = static_cast<CDerived*>(a);
dynamic_cast • used only with pointers and references to objects. • Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class. • always successful when we cast a class to one of its base classes CBase b; CBase* pb; CDerived d; CDerived* pd; pb = dynamic_cast<CBase*>(&d); // ok: derived-to-base pd = dynamic_cast<CDerived*>(&b); // wrong: base-to-derived
Abstract Base Class • No keyword “abstract” in C++ • To make an abstract class, include at least one pure virtual function. virtual intGetValue() = 0; • An abstract class cannot be instantiated! • any derived class must define a body for the pure virtual function, or that derived class will be considered an abstract base class as well. • An interface can be implemented in C++ as an abstract base class with only pure virtual functions.
Example class IntSet : public IntContainer { public: void add(int x); void remove(int x); bool contains(int x); protected: int *nums; // growable array }; class IntContainer { public: IntContainer() : count(0) { } virtual void add(int x) = 0; virtual void remove(int x) = 0; virtual bool contains(int x) const = 0; intsize() const { return count; } protected: intcount; }; IntContainer cont1; // ILLEGAL! IntContainer*cont2; // (legal) cont2 = new IntContainer; // ILLEGAL! cont2 = new IntSet; // (legal)