Title: Base class, Pet
1Base class, Pet
// Pet is a base class class Pet public
Pet(string name) string I() void
goes() private string voice() string
my_name
PetPet(string name) my_name(name) string
PetI() return my_name string
Petvoice() return "???" void
Petgoes() cout ltlt I() ltlt " goes " ltlt voice()
ltlt "!\n" int main() Pet t("Tommy") t.goe
s() ......
Tommy goes ???!
2Derived classes, Cat Dog
// Pet, base class class Pet public
Pet(string name) string I() void
goes() private string voice() string
my_name
// Dog, derived class class Dog public Pet
public Dog(string name) private
string voice()
// Cat, derived class class Cat public Pet
public Cat(string name) private
string voice()
string Dogvoice() return "Woof!! Woof!"
string Catvoice() return "Meow!! Meow!"
redefine voice() inherit goes()
call this goes()
int main() Dog d("Lucky") Cat
c("Mimi") d.goes() c.goes() ........
Lucky goes ???! Mimi goes ???!
3One solution Redefine goes() voice()
// Pet, base class class Pet public
Pet(string name) string I() void
goes() private string voice() string
my_name
// Dog, derived class class Dog public Pet
public Dog(string name) void
goes() private string voice()
// Cat, derived class class Cat public Pet
public Cat(string name) void
goes() private string voice()
call this voice()
call this voice()
string Dogvoice() return "Woof!! Woof!"
string Catvoice() return "Meow!! Meow!"
int main() Dog d("Lucky") Cat
c("Mimi") d.goes() c.goes() ........
Lucky goes Woof!! Woof!! Mimi goes Meow!!
Meow!!
4A better solution Polymorphism
Polymorphism
allows a function to carry more than one
definitions, and which one should be used is not
determined during the compiling time. Namely, a
proper definition is bonded to the function
during the run time -- a.k.a. Dynamic Binding,
Late Binding.
In C, we call such functions -- virtual
functions, they don't have to be actually defined
during the compiling time.
5How this works
when goes() calls voice(), the definition of
voice() will be inherited backwards from
the calling class.
virtual function
Pet I() goes() voice()
Dog I() goes() voice()
Cat I() goes() voice()
BigCat I() goes() voice()
Wolf I() goes() voice()
6Virtual functions
// Cat, derived class class Cat public Pet
public Cat(string name) private
string voice()
// Dog, derived class class Dog public Pet
public Dog(string name) private
string voice()
// Pet, base class class Pet public
Pet(string name) string I() void
goes() private virtual string voice()
string my_name
string Dogvoice() return "Woof!! Woof!"
string Catvoice() return "Meow!! Meow!"
redefine voice() inherit goes()
int main() Dog d("Lucky") Cat
c("Mimi") d.goes() c.goes() ........
Lucky goes Woof!! Woof!! Mimi goes Meow!!
Meow!!
7Change non-virtual to virtual
Virtual function, overriding
Function, defining
need to redefine, otherwise likes() defined in
the base class will be inherited and it will call
the food() defined in the bases class, which is
not virtual.
Inheritance
call
call
Overloading
Mammal likes()food() goes()voice()
likes()food() goes()voice()
likes()food() goes()voice()
Cat
Dog
call
likes()food() goes()voice()
likes()food() goes()voice()
Wolf
Lion
8Why virtual functions?
Virtual function, overriding
Function, defining
Inheritance
- The function f() is
- too complicate, but
- identical,
- for derived class designers to program. Also,
- f() needs to call function g(),
- and g() needs to be redefined in different
derived classes. - In this case, g() should be a virtual function
so the function f() called from a derived class
can call the appropriate g() for the derived
class.
Base classf() g()
Derived 1f() g()
Derived 2f() g()
Derived 3f() g()
Derived 4f() g()
9An Abstract class
A class contains pure virtual functions.
// Pet, abstract class class Pet public
...... private virtual string voice() 0
.....
There is no need to actually define a pure
virtual function.
- An abstract class can't be instantiated, but
only be used as a base class. - A class remains abstract if it inherits an
undefined pure virtual function and the pure
function remains undefined in the class.
10Sample Program
include ltiostreamgt include ltstringgt using
namespace std // Base class class Pet
public Pet(string name) // constructor
void goes() // NOT a virtual function
void likes() // NOT a virtual function
string I() // NOT a virtual
function private virtual string voice()0
// a pure virtual fun, polymorphic string
food() // NOT a virtual function string
my_name
11Pet
PetPet(string name) my_name(name) void
Petgoes() cout ltlt I() ltlt " goes " ltlt
voice() ltlt "!\n" void Petlikes()
cout ltlt I() ltlt " likes " ltlt food() ltlt
"!\n" string PetI() return
my_name string Petfood() return
"????"
12Dog
// Derived Class class Dog public Pet
public Dog(string name) //
constructor private string voice() //
overriding string food() // redefining
DogDog(string name) Pet(name)
string Dogvoice() return "Woof!!
Woof!" string Dogfood() return
"bone"
13Cat
// Derived Class class Cat public Pet
public Cat(string name) // constructor
void likes() // redefining private
string voice() // overriding virtual
string food() // changing to virtual and
redefining it CatCat(string name)
Pet(name) void Catlikes() cout ltlt
I() ltlt " likes " ltlt food() ltlt "!\n" string
Catvoice() return "Meow!! Meow!" string
Catfood() return "fish"
14BigCat
// Derived Class class BigCat public Cat
public BigCat(string name) //
constructor private string voice() //
overriding string food() // overriding
BigCatBigCat(string name) Cat(name)
string BigCatvoice() return
"Grrr!! Grrr!" string BigCatfood()
return "zebras"
15Main
int main() // Pet tommy("Tommy") // Abstract
class, can't be instantiated Dog
lucky("Lucky") cout ltlt "\n" ltlt lucky.I() ltlt "
is a Dog.\n" lucky.goes()
lucky.likes() Cat mimi("Mimi") cout
ltlt "\n" ltlt mimi.I() ltlt " is a Cat.\n"
mimi.goes() mimi.likes() BigCat
simba("Simba") cout ltlt "\n" ltlt simba.I()
ltlt " is a BigCat.\n" simba.goes()
simba.likes() cout ltlt endl return 0
Lucky is a Dog. Lucky goes Woof!! Woof!! Lucky
likes ????! Mimi is a Cat. Mimi goes Meow!!
Meow!! Mimi likes fish! Simba is a BigCat. Simba
goes Grrr!! Grrr!! Simba likes zebras!
16Assignment and Virtual functions
Base class -- Cat
fish
Meow
likes()food() goes()voice()
int main() Cat mimi("Mimi"), BigCat
simba("Simba") Cat t("temp") t mimi
t.goes() t.likes() cout ltlt endl
simba.goes() simba.likes() cout ltlt
endl t simba t.goes()
t.likes() ....
virtual
virtual
likes()food() goes()voice()
Grrrr
zebras
Derived class -- BigCat
Mimi goes Meow!! Meow!! Mimi likes fish! Simba
goes Grrr!! Grrr!! Simba likes zebras! Simba
goes Meow!! Meow!! Simba likes fish!
17Pointers and Virtual functions
Base class -- Cat
fish
Meow
likes()food() goes()voice()
int main() ..... Cat mimi("Mimi"),
BigCat simba("Simba") Cat p p
mimi p-gtgoes() p-gtlikes() cout
ltlt endl p simba p-gtgoes()
p-gtlikes() ....
virtual
virtual
likes()food() goes()voice()
Grrrr
zebras
Derived class -- BigCat
Mimi goes Meow!! Meow!! Mimi likes fish! Simba
goes Grrr!! Grrr!! Simba likes zebras!
18Trade-off Efficiency
A virtual function uses dynamic binding (in other
words, late binding). This requires more storage
and makes the program runs slower.
- In C, by default, a member function is not
virtual functions unless specified by the
modifier, virtual. - in Java, all member functions are virtual.