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)  
        self._radius = r
        
    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.circle(self._radius)
        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 , '\"'
        
        
    def __add__(self,d2):           #add distance to this one
        
        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 , '\"'
        
        
        
def add(d1,d2):                 #add distance to this one
    
    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
        
    def __eq__(self,a):                #overloaded == operator
        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
        
    def __eq__(self,a):                   #overloaded == operator
        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
        print '(addr =',hex(id(self.__psc)),')'   #print address
        
        
    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):
        print "my object's address is",hex(id(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
my object's address is 0x375a188L
my object's address is 0x375a208L

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
        
    def __eq__(self,a):                 #overloaded == operator
        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
        print '(addr =',hex(id(self.__psc)),')'   #print address
        
        
        
    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 [ ]: