# Chapter 11: Virtual Functions¶

## Example 11.1, Page Number 505¶

In [1]:
class Base:               #Base class
def show(self):       #virtual function
print 'Base'

class Derv1(Base):        #derived class 1
def show(self):
print 'Derv1'

class Derv2(Base):        #derived class 2
def show(self):
print 'Derv2'

dv1 = Derv1()             #object of derived class 1
dv2 = Derv2()             #object of derived class 2

ptr = [Base()]            #pointer to base class

ptr[0] = dv1              #put address of dv1 in pointer
ptr[0].show()             #execute show()

ptr[0] = dv2              #put address of dv2 in pointer
ptr[0].show()             #execute show()

#in python all functions are virtual by default that is why here output is diffrent from the book

Derv1
Derv2


## Example 11.2, Page Number 507¶

In [2]:
class Base:                #base class
def show(self):        #virtual function
print 'Base'

class Derv1(Base):         #derived class 1
def show(self):
print 'Derv1'

class Derv2(Base):         #derived class 2
def show(self):
print 'Derv2'

dv1 = Derv1()             #object of derived class 1
dv2 = Derv2()             #object of derived class 2

ptr = [Base()]            #pointer to base class

ptr[0] = dv1              #put address of dv1 in pointer
ptr[0].show()             #execute show()

ptr[0] = dv2              #put address of dv2 in pointer
ptr[0].show()             #execute show()

Derv1
Derv2


## Example 11.3, Page Number 510¶

In [3]:
class Base:             #base class
def show(self):     #pure virtual function
pass

class Derv1(Base):      #derived class 1
def show(self):
print 'Derv1'

class Derv2(Base):      #derived class 2
def show(self):
print 'Derv2'

arr = [Base(),Base()]   #array of pointers to base class
dv1 = Derv1()           #object of derived class 1
dv2 = Derv2()           #object of derived class 2

arr[0] = dv1            #put address of dv1 in pointer
arr[1] = dv2            #put address of dv2 in pointer

arr[0].show()           #execute show() in both objects
arr[1].show()

Derv1
Derv2


## Example 11.4, Page Number 512¶

In [4]:
class person:        #person class

def getName(self):
self._name = raw_input("   Enter name: ")

def putName(self):
print 'Name is:',self._name

def getData(self):           #pure virtual function
pass

def isOutstanding(self):     #pure virtual function
pass

class student(person):           #student class

def getData(self):           #get student data from user
person.getName(self)
self.__gpa = input('   Enter student\'s GPA: ')    #grade point aerage

def isOutstanding(self):
if self.__gpa > 3.5:
return True
else:
return False

class professor(person):          #professor class

def getData(self):            #get professor data from user
person.getName(self)
self.__numPubs = input('   Enter number of professor\'s publications: ')      #number of papers published

def isOutstanding(self):
if self.__numPubs > 100:
return True
else:
return False

persPtr = [person()]*100          #array of persons
n = 0                             #number of persons on list

while True:
choice = raw_input('Enter student or professor (s/p): ')

if choice=='s':
persPtr[n] = student()           #put new student in array
else:
persPtr[n] = professor()         #put new professor in array

persPtr[n].getData()                 #get data for person
n+=1

choice = raw_input('   Enter another (y/n)? ')          #do another person?

if choice=='n':             #cycle untill not 'y'
break

print ''
for j in range(n):              #print names of all persons, and say if outstanding
persPtr[j].putName()

if persPtr[j].isOutstanding():
print '   This person is outstanding'

Enter student or professor (s/p): s
Enter name: Timmy
Enter student's GPA: 1.2
Enter another (y/n)? y
Enter student or professor (s/p): s
Enter name: Brenda
Enter student's GPA: 3.9
Enter another (y/n)? y
Enter student or professor (s/p): s
Enter name: Sandy
Enter student's GPA: 2.4
Enter another (y/n)? y
Enter student or professor (s/p): p
Enter name: Shipley
Enter number of professor's publications: 714
Enter another (y/n)? y
Enter student or professor (s/p): p
Enter name: Wainright
Enter number of professor's publications: 13
Enter another (y/n)? n

Name is: Timmy
Name is: Brenda
This person is outstanding
Name is: Sandy
Name is: Shipley
This person is outstanding
Name is: Wainright


## Example 11.5, Page Number 515¶

In [5]:
from turtle import Turtle,setup,done       #importing turtles library

class shape:                                   #base class
def __init__(self,x=0,y=0,fc="white"):     #constructor
self._xCo = x                          #coordinate for shape
self._yCo = y
self._fillcolor = fc                   #color for shape

def draw(self,a):              #virtual draw function
a.color(self._fillcolor)

class ball(shape):                 #defining circle class

def __init__(self,x,y,r,fc):     #constructor for set circle attribute
shape.__init__(self,x,y,fc)

def draw(self):      #draw the circle
setup()
turtle = Turtle()
turtle.begin_fill()

shape.draw(self,turtle)

turtle.up()
turtle.goto(self._xCo,self._yCo)
turtle.down()
turtle.end_fill()
turtle.hideturtle()
done()

class rect(shape):          #defining rectangle class

def __init__(self,x,y,h,w,fc):     #constructor
shape.__init__(self,x,y,fc)
self._height = h
self._weight = w

def draw(self):      #draw the rectangle
setup()
turtle = Turtle()
turtle.begin_fill()

shape.draw(self,turtle)

turtle.up()
turtle.goto(self._xCo,self._yCo)
turtle.down()
turtle.forward(self._weight)
turtle.left(90)
turtle.forward(self._height)
turtle.left(90)
turtle.forward(self._weight)
turtle.left(90)
turtle.forward(self._height)
turtle.end_fill()
turtle.hideturtle()
done()

class tria(shape):          #defining triangle class

def __init__(self,x,y,h,fc):     #constructor
shape.__init__(self,x,y,fc)
self._height = h

def draw(self):      #draw the triangle
setup()
turtle = Turtle()
turtle.begin_fill()

shape.draw(self,turtle)

turtle.up()
turtle.goto(self._xCo,self._yCo)
turtle.down()
turtle.forward(self._height)
turtle.left(120)
turtle.forward(self._height)
turtle.left(120)
turtle.forward(self._height)
turtle.end_fill()
turtle.hideturtle()
done()

pShapes = [shape()]*3                #array of shapes define three shapes

pShapes[0] = ball(40,12,5,"blue")                  #create circle
pShapes[1] = rect(12,7,10,15,"red")                #create rectangle
pShapes[2] = tria(60,7,11,"green")                 #create triangle

for j in range(3):            #draw all shape
pShapes[j].draw()


## Example 11.6, Page Number 517¶

In [6]:
class Base:
def __del__(self):            #non virtual destructor
print 'Base destroyed'

class Derv(Base):
def __del__(self):
print 'Derv destroyed'

pBase = [Base()]

del pBase[0]

Base destroyed


## Example 11.7, Page Number 521¶

In [7]:
class alpha:
def __init__(self):          #no-arg constructor
self.__data = 3

class beta:
def __init__(self):          #no-arg constructor
self.__data = 7

def frifunc(a,b):                #friend function of both alpha and beta classes
return a._alpha__data + b._beta__data

aa = alpha()
bb = beta()

print frifunc(aa,bb)             #call the function

10


## Example 11.8, Page Number 522¶

In [8]:
class Distance:             #class Distance

def __init__(self,ft=0,inc=0.0):        #constructor

if isinstance(ft,float):            #one argument
fltfeet = ft
self.__feet = int(fltfeet)                    #feet is integer part
self.__inches = 12*(fltfeet-self.__feet)      #inches is what's left

else:                                   #two arguments
self.__feet = ft
self.__inches = inc

def showdist(self):             #display Distance
print self.__feet , '\' -' , self.__inches , '\"'

if isinstance(d2,float):
d2 = Distance(d2)

f = self.__feet + d2.__feet         #add the feet
i = self.__inches + d2.__inches     #add the inches

if i >= 12.0:               #if total exceeds 12.0,
i -= 12.0               #then decrease inches by 12.0 and
f += 1                  #increase feet by 1

return Distance(f,i)        #return new Distance with sum

d1 = Distance(2.5)             #constructor converts float feet to Distance
d2 = Distance(1.25)
d3 = Distance()

print 'd1 =',;d1.showdist()
print 'd2 =',;d2.showdist()

d3 = d1 + 10.0                 #Distance + feet: OK
print 'd3 =',;d3.showdist()

d1 = 2 ' - 6.0 "
d2 = 1 ' - 3.0 "
d3 = 12 ' - 6.0 "


## Example 11.9, Page Number 524¶

In [9]:
class Distance:           #class Distance

def __init__(self,ft=0,inc=0.0):    #constructor

if isinstance(ft,float):        #one argument
fltfeet = ft
self.__feet = int(fltfeet)                       #feet is integer part
self.__inches = 12*(fltfeet-self.__feet)         #inches is what's left

else:                           #two arguments
self.__feet = ft
self.__inches = inc

def showdist(self):                 #display Distance
print self.__feet , '\' -' , self.__inches , '\"'

if isinstance(d2,float):
d2 = Distance(d2)

if isinstance(d1,float):
d1 = Distance(d1)

f = d1._Distance__feet + d2._Distance__feet         #add the feet
i = d1._Distance__inches + d2._Distance__inches     #add the inches

if i >= 12.0:               #if total exceeds 12.0,
i -= 12.0               #then decrease inches by 12.0 and
f += 1                  #increase feet by 1

return Distance(f,i)        #return new Distance with sum

d1 = Distance(2.5)              #constructor converts float feet to Distance
d2 = Distance(1.25)
d3 = Distance()

print 'd1 =',;d1.showdist()
print 'd2 =',;d2.showdist()

d3 = add(d1,10.0)                #Distance + feet: OK
print 'd3 =',;d3.showdist()

d3 = add(10.0,d1)                #feet + Distance: OK
print 'd3 =',;d3.showdist()

d1 = 2 ' - 6.0 "
d2 = 1 ' - 3.0 "
d3 = 12 ' - 6.0 "
d3 = 12 ' - 6.0 "


## Example 11.10, Page Number 526¶

In [10]:
class Distance:         #class Distance

def __init__(self,ft=0,inc=0.0):      #constructor
self.__feet = ft
self.__inches = inc

def showdist(self):         #display Distance
print self.__feet , '\' -' , self.__inches , '\"'

def square(self):                                   #returns square of this distance
fltfeet = self.__feet + self.__inches/12        #convert to float
feetsqrd = fltfeet*fltfeet                      #find the square
return feetsqrd                                 #return square feet

dist = Distance(3,6.0)

sqft = dist.square()                   #return square of dist

print 'Distance =',;dist.showdist()           #display distance and square
print 'Square =',sqft,'square feet'

Distance = 3 ' - 6.0 "
Square = 12.25 square feet


## Example 11.11, Page Number 527¶

In [11]:
class Distance:         #class Distance

def __init__(self,ft=0,inc=0.0):       #constructor
self.__feet = ft
self.__inches = inc

def showdist(self):       #display Distance
print self.__feet , '\' -' , self.__inches , '\"'

#friend function

def square(d):                                                 #returns square of this distance
fltfeet = d._Distance__feet + d._Distance__inches/12       #convert to float
feetsqrd = fltfeet*fltfeet                                 #find the square
return feetsqrd                                            #return square feet

dist = Distance(3,6.0)

sqft = square(dist)            #return square of dist

print 'Distance =',;dist.showdist()           #display distance and square
print 'Square =',sqft,'square feet'

Distance = 3 ' - 6.0 "
Square = 12.25 square feet


## Example 11.12, Page Number 528¶

In [12]:
class alpha:
def __init__(self):          #constructor
self.__data1 = 99

class beta:
def func1(self,a):                     #it can access private member of alpha class through a
print 'data1 =',a._alpha__data1

def func2(self,a):                     #it can access private member of alpha class through a
print 'data1 =',a._alpha__data1

a = alpha()
b = beta()

b.func1(a)
b.func2(a)

data1 = 99
data1 = 99


## Example 11.13, Page Number 529¶

In [13]:
class gamma:
__total = 0            #total object of this classs

def __init__(self):                 #no-arg constructor
gamma.__total += 1              #add another object
self.__id = gamma.__total       #ID number of this object   and   ID equals to current total

def __del__(self):                  #destructor
gamma.__total -= 1
print 'Destroyed ID number',self.__id

def showtotal(self):                #function
print 'Total is',gamma.__total

def showid(self):                   #function
print 'ID number is',self.__id

g1 = gamma()
g1.showtotal()

g2 = gamma()
g3 = gamma()
g1.showtotal()

g1.showid()
g2.showid()
g3.showid()

print '-----------end of program-----------'

del g3
del g2
del g1

Total is 1
Total is 3
ID number is 1
ID number is 2
ID number is 3
-----------end of program-----------
Destroyed ID number 3
Destroyed ID number 2
Destroyed ID number 1


## Example 11.14, Page Number 533¶

In [14]:
class alpha:
def __init__(self,d=0):             #constructor

if isinstance(d,int):
self.__data = d
else:
self.__data = d.__data

def display(self):                 #display data
print self.__data

self.__data = a.__data         #not done automatically
print 'Assignment operator invoked'

return alpha(self.__data)      #return copy of this alpha

a1 = alpha(37)
a2 = alpha()

a2 = (a2 == a1)                 #invoke overloaded ==
print 'a2 =',;a2.display()      #display a2

a3 = alpha(a2)                  #does not invoke ==
print 'a3 =',;a3.display()      #display a3

Assignment operator invoked
a2 = 37
a3 = 37


## Example 11.15, Page Number 536¶

In [15]:
class alpha:

def __init__(self,d=0):               #constructor
if isinstance(d,int):
self.__data = d
else:
self.__data = d.__data
print 'copy constructor invoked'

def display(self):                    #display data
print self.__data

self.__data = a.__data
print 'Assignment operator invoked'
return alpha(self.__data)

a1 = alpha(37)
a2 = alpha()

a2 = (a2 == a1)                #invoke overloaded ==
print 'a2 =',;a2.display()     #display a2

a3 = alpha(a2)                 #invoke copy constructor
print 'a3 =',;a3.display()     #display a3

Assignment operator invoked
a2 = 37
copy constructor invoked
a3 = 37


## Example 11.16, Page Number 543¶

In [16]:
class strCount:                        #keep track of number of unique strings

def __init__(self,s):              #one - arg constructor
self.__str = s                 #copy argument to string
self.__count = 1               #number of instances and start count at 1

def __del__(self):                 #destructor
del self.__str                 #delete the string

class String:                          #string class

def __init__(self,s=""):           #constructor

if isinstance(s,String):
self.__psc = s.__psc
self.__psc._strCount__count += 1
else:
self.__psc = strCount(s)

def __del__(self):          #destructor

if self.__psc._strCount__count == 1:         #if we are its last user, delete the string
del self.__psc

else:
self.__psc._strCount__count -= 1         #otherwise decrement its count

def display(self):                            #display the string
print self.__psc._strCount__str,          #print string

def __eq__(self,s):                           #assign the string

if self.__psc._strCount__count == 1:      #if we are its last user, delete the string
del self.__psc

else:
self.__psc._strCount__count -= 1      #otherwise decrement its count

self.__psc = s.__psc                      #use argument's strCount
self.__psc._strCount__count += 1          #increment its count

return s

s3 = String("When the fox preaches, look to your geeses.")
print 's3 =',;s3.display()           #display s3

s1 = String()                       #define string
s1 = (s1==s3)                       #assign it another string
print 's1 =',;s1.display()           #display it

s2 = String(s3)                     #initialize with string
print 's2 =',;s2.display()           #display it

s3 = When the fox preaches, look to your geeses. (addr = 0x3ac0988L )
s1 = When the fox preaches, look to your geeses. (addr = 0x3ac0988L )
s2 = When the fox preaches, look to your geeses. (addr = 0x3ac0988L )


## Example 11.17, Page Number 547¶

In [17]:
class where:
__charray = []*10          #copies 10 bytes

def reveal(self):

w1 = where()         #make three objects
w2 = where()
w3 = where()

w1.reveal()          #see where they are
w2.reveal()
w3.reveal()

my object's address is 0x38ec3c8L


## Example 11.18, Page Number 548¶

In [18]:
class what:
def tester(self):
self.__alpha = 11          #same as alpha = 11
print self.__alpha         #same as print alpha

w = what()
w.tester()

11


## Example 11.19, Page Number 549¶

In [19]:
class alpha:
def __init__(self,d=None):          #constructor
self.__data = d

def display(self):                  #display data
print self.__data

self.__data = a.__data          #not done automatically
print 'Assignment operator invoked'
return alpha(self.__data)       #return copy of this alpha

a1 = alpha(37)
a2 = alpha()
a3 = alpha()

a3 = a3 == a2 == a1              #invoke overloaded ==, twice
print 'a2 =',;a2.display()       #display a2
print 'a3 =',;a3.display()       #display a3

Assignment operator invoked
Assignment operator invoked
a2 = 37
a3 = 37


## Example 11.20, Page Number 550¶

In [20]:
class strCount:                    #keep track of number of unique strings

def __init__(self,s):              #one - arg constructor
self.__str = s                 #copy argument to string
self.__count = 1               #number of instances and start count at 1

def __del__(self):                 #destructor
del self.__str                 #delete the string

class String:

def __init__(self,s=""):           #constructor

if isinstance(s,String):
print 'COPY CONSTRUCTOR'
self.__psc = s.__psc
self.__psc._strCount__count += 1
else:
self.__psc = strCount(s)

def __del__(self):          #destructor

if self.__psc._strCount__count == 1:      #if we are its last user, delete the string
del self.__psc

else:
self.__psc._strCount__count -= 1      #otherwise decrement its count

def display(self):                            #display the string
print self.__psc._strCount__str,          #print string

def __eq__(self,s):
print 'ASSIGNMENT'

if self.__psc._strCount__count == 1:      #if we are its last user, delete the string
del self.__psc

else:
self.__psc._strCount__count -= 1      #otherwise decrement its count

self.__psc = s.__psc                      #use argument's strCount
self.__psc._strCount__count += 1          #increment its count

return self

s3 = String("When the fox preaches, look to your geeses.")
print 's3 =',;s3.display()        #display s3

s1 = String()                    #define strings
s2 = String()

s1 = s1 == s2==s3                #assign them

print 's1 =',;s1.display()        #display it
print 's2 =',;s2.display()

s3 = When the fox preaches, look to your geeses. (addr = 0x3ac0f88L )
ASSIGNMENT
ASSIGNMENT
s1 = When the fox preaches, look to your geeses. (addr = 0x3ac0f88L )
s2 = When the fox preaches, look to your geeses. (addr = 0x3ac0f88L )


## Example 11.21, Page Number 553¶

In [21]:
class Base:
def vertFunc(self):           #needed for dynamic cast
pass

class Derv1(Base):
pass

class Derv2(Base):
pass

def isDerv1(pUnknown):               #unKnown subclass of base
if isinstance(pUnknown,Derv1):
return True
else:
return False

d1 = Derv1()
d2 = Derv2()

if isDerv1(d1):
print 'd1 is a member of the Derv1 class'
else:
print 'd1 is not a member of the Derv1 class'

if isDerv1(d2):
print 'd2 is a member of the Derv1 class'
else:
print 'd2 is not a member of the Derv1 class'

d1 is a member of the Derv1 class
d2 is not a member of the Derv1 class


## Example 11.22, Page Number 555¶

In [22]:
class Base:
def __init__(self,b=0):
self._ba = b

def vertFunc(self):           #needed for dynamic cast
pass

def show(self):
print 'Base: ba =',self._ba

class Derv(Base):
def __init__(self,b,d):
self._ba = b
self.__da = d

def show(self):
print 'Derv: ba =',self._ba,'da =',self.__da

pBase = Base(10)         #Base class object
pDerv = Derv(21,22)      #derv class object

pBase.show()             #"Base: ba=10"

pBase = Derv(31,32)
pDerv = pBase
pDerv.show()

Base: ba = 10
Derv: ba = 31 da = 32


## Example 11.23, Page Number 556¶

In [23]:
class Base:
def vertFunc(self):
pass

class Derv1(Base):
pass

class Derv2(Base):
pass

def displayName(pB):                    #display name of class
print 'pointer to an object of',
#to show from which class this object belongs
if isinstance(pB,Derv1):
print 'Derv1'
if isinstance(pB,Derv2):
print 'Derv2'

pBase = Derv1()            #object of Derv1
displayName(pBase)

pBase = Derv2()            #object of Derv2
displayName(pBase)

pointer to an object of Derv1
pointer to an object of Derv2

In [ ]: