example-virtual-functions.py 3.77 KB
Newer Older
1
2
3
4
5
6
#!/usr/bin/env python
from __future__ import print_function
import sys
sys.path.append('.')

from example import ExampleVirt, runExampleVirt, runExampleVirtVirtual, runExampleVirtBool
7
from example import A_Repeat, B_Repeat, C_Repeat, D_Repeat, A_Tpl, B_Tpl, C_Tpl, D_Tpl
8
9
from example import NCVirt, NonCopyable, Movable

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

class ExtendedExampleVirt(ExampleVirt):
    def __init__(self, state):
        super(ExtendedExampleVirt, self).__init__(state + 1)
        self.data = "Hello world"

    def run(self, value):
        print('ExtendedExampleVirt::run(%i), calling parent..' % value)
        return super(ExtendedExampleVirt, self).run(value + 1)

    def run_bool(self):
        print('ExtendedExampleVirt::run_bool()')
        return False

    def pure_virtual(self):
        print('ExtendedExampleVirt::pure_virtual(): %s' % self.data)


ex12 = ExampleVirt(10)
print(runExampleVirt(ex12, 20))
try:
    runExampleVirtVirtual(ex12)
except Exception as e:
    print("Caught expected exception: " + str(e))

ex12p = ExtendedExampleVirt(10)
print(runExampleVirt(ex12p, 20))
print(runExampleVirtBool(ex12p))
runExampleVirtVirtual(ex12p)
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

class VI_AR(A_Repeat):
    def unlucky_number(self):
        return 99
class VI_AT(A_Tpl):
    def unlucky_number(self):
        return 999

class VI_CR(C_Repeat):
    def lucky_number(self):
        return C_Repeat.lucky_number(self) + 1.25
class VI_CT(C_Tpl):
    pass
class VI_CCR(VI_CR):
    def lucky_number(self):
        return VI_CR.lucky_number(self) * 10
class VI_CCT(VI_CT):
    def lucky_number(self):
        return VI_CT.lucky_number(self) * 1000


class VI_DR(D_Repeat):
    def unlucky_number(self):
        return 123
    def lucky_number(self):
        return 42.0
class VI_DT(D_Tpl):
    def say_something(self, times):
        print("VI_DT says:" + (' quack' * times))
    def unlucky_number(self):
        return 1234
    def lucky_number(self):
        return -4.25

classes = [
74
75
76
77
78
79
    # A_Repeat, A_Tpl, # abstract (they have a pure virtual unlucky_number)
    VI_AR, VI_AT,
    B_Repeat, B_Tpl,
    C_Repeat, C_Tpl,
    VI_CR, VI_CT, VI_CCR, VI_CCT,
    D_Repeat, D_Tpl, VI_DR, VI_DT
80
81
82
83
84
85
86
87
88
89
]

for cl in classes:
    print("\n%s:" % cl.__name__)
    obj = cl()
    obj.say_something(3)
    print("Unlucky = %d" % obj.unlucky_number())
    if hasattr(obj, "lucky_number"):
        print("Lucky = %.2f" % obj.lucky_number())

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
class NCVirtExt(NCVirt):
    def get_noncopyable(self, a, b):
        # Constructs and returns a new instance:
        nc = NonCopyable(a*a, b*b)
        return nc
    def get_movable(self, a, b):
        # Return a referenced copy
        self.movable = Movable(a, b)
        return self.movable

class NCVirtExt2(NCVirt):
    def get_noncopyable(self, a, b):
        # Keep a reference: this is going to throw an exception
        self.nc = NonCopyable(a, b)
        return self.nc
    def get_movable(self, a, b):
        # Return a new instance without storing it
        return Movable(a, b)

ncv1 = NCVirtExt()
print("2^2 * 3^2 =")
ncv1.print_nc(2, 3)
print("4 + 5 =")
ncv1.print_movable(4, 5)
ncv2 = NCVirtExt2()
print("7 + 7 =")
ncv2.print_movable(7, 7)
try:
    ncv2.print_nc(9, 9)
    print("Something's wrong: exception not raised!")
except RuntimeError as e:
    # Don't print the exception message here because it differs under debug/non-debug mode
    print("Caught expected exception")
123
124
125
126
127
128
129
130
131
132
133
134
135

from example import ConstructorStats
del ex12
del ex12p
del obj
del ncv1
del ncv2
cstats = [ConstructorStats.get(ExampleVirt), ConstructorStats.get(NonCopyable), ConstructorStats.get(Movable)]
print("Instances not destroyed:", [x.alive() for x in cstats])
print("Constructor values:", [x.values() for x in cstats])
print("Copy constructions:", [x.copy_constructions for x in cstats])
print("Move constructions:", [cstats[i].move_constructions >= 1 for i in range(1, len(cstats))])