Yan Shi CSSE 2630 Lecture Notes Modern ObjectOriented Concepts Modern objectoriented OO languages provide 3 capabilities encapsulation inheritance polymorphism which can improve the design structure and reusability of code ID: 578135
Download Presentation The PPT/PDF document "7. Inheritance and Polymorphism" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
7. Inheritance and Polymorphism
Yan Shi
CS/SE 2630 Lecture NotesSlide2
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.Slide3
Inheritance in C++
Syntax:
class
X
: public
Y
Example:
class Manager: public EmployeeSlide4
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 knows 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.Slide5
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?
Can a derived class access private members of the base class?Slide6
Member Initialization List
For class constructors only
can be used to overload constructors
Manager
::Manager(
string
n
,
float
rate
,
bool
isSalaried
)
:
Employee
(
n
,
rate
)
{
salaried =
isSalaried
;
}
can be used to initialize data members in constructors
Employee(
string
n
,
float
rate
) :
Person( n ),
payRate
(
rate
) {}Slide7
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.Slide8
Polymorphism
polymorphism
means 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
functionsSlide9
Base Class Pointer
We can
assign a pointer to a
base
class to a variable declared using the
derived
class
Employee
*
emp
;
emp
=
new
Manager
( 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
!
virtual
float
Pay(
float
hoursWorked
)
const
;Slide10
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
never
virtual!
Why?Slide11
vtable
A virtual method/function/call table is to support run-time method binding.
contains an array of 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
.Slide12
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()Slide13
Abstract Base Class
No keyword “abstract” in C++
To make an abstract class, include at least one
pure virtual function
.
virtual
int
GetValue
()
= 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.Slide14
Example
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; int size()
const { return count; } protected:
int
count;
};
class
IntSet : public IntContainer { public: void add(int x); void remove(int x); bool contains(int x); protected: int *nums; // growable array };
IntContainer
cont1;
// ILLEGAL!
IntContainer
*cont2; // (legal)
cont2
= new
IntContainer
;
//
ILLEGAL!
cont2
= new
IntSet
; // (legal)Slide15
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
may produce
either a run-time error or a unexpected result
.
dynamic_cast
<
new_type
> (expression
)
static_cast
<new_type> (expression)reinterpret_cast <new_type> (expression)const_cast <new_type> (expression)for more information: http://www.cplusplus.com/doc/tutorial/typecasting/Slide16
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); //validSlide17
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