Monday, April 30, 2012

How to Programmatically Set Log File Path in Logback

This example uses SLF4J with Logback. In order to programmatically set log file path, we need to programmatically create a FileAppender and append it into our own logger (in this example it's "MY_LOGGER").
LogbackFileUtils.java
1
2
3
4
5
6
7
8
9
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
39
40
41
42
43
44
45
46
47
48
49
50
package test;
 
import org.slf4j.LoggerFactory;
 
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
 
class LogbackFileUtils {
     
    public static final String MY_LOGGER = "MY_LOGGER";
    private static FileAppender<ILoggingEvent> fileAppender;
    private static boolean initialized = false;
     
    public static void init() {
        if (!initialized) {
            LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
            Logger myLogger = loggerContext.getLogger(MY_LOGGER);
             
            PatternLayoutEncoder encoder = new PatternLayoutEncoder();
            encoder.setContext(loggerContext);
            encoder.setPattern("%d{HH:mm:ss.SSS} [%-5level] %msg %n");
            encoder.start();
             
            fileAppender = new FileAppender<ILoggingEvent>();
            fileAppender.setContext(loggerContext);
            fileAppender.setName("MY_FILE_LOGGER");
            fileAppender.setAppend(false);
            fileAppender.setEncoder(encoder);
            myLogger.addAppender(fileAppender);
             
            initialized = true;
        }
    }
     
    public static void start(String filePath) {
        init();
        stop();
        fileAppender.setFile(filePath);
        fileAppender.start();
    }
     
    public static void stop() {
        if (fileAppender.isStarted()) {
            fileAppender.stop();
        }
    }
}
This example hardcodes the pattern. We can improve this example by copying the pattern from "STDOUT" logger.

logback.xml
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%-5level] %msg %n</pattern>
    </encoder>
  </appender>
 
  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
LogbackTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package test;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class LogbackTest {
 
    private static Logger logger = LoggerFactory.getLogger(LogbackFileUtils.MY_LOGGER);
     
    public static void main(String[] args) {
        LogbackFileUtils.start("first.log");
        logger.info("1st file - This is an info message");
        logger.debug("1st file - This is a debug message");
        logger.error("1st file - This is an error message");
        LogbackFileUtils.stop();
         
        LogbackFileUtils.start("second.log");
        logger.info("2nd file - This is an info message");
        logger.debug("2nd file - This is a debug message");
        logger.error("2nd file - This is an error message");
        LogbackFileUtils.stop();
         
        logger.info("console only - This is an info message");
        logger.debug("console only - This is a debug message");
        logger.error("console only - This is an error message");
    }
}
We need to make sure we call the right logger (MY_LOGGER) and not anything else. There will be two files generated, first.log and second.log.

Sunday, April 22, 2012

How to Implement Queue in Python

Below are my simple implementations of queue (FIFO) using array list (some wasted space) and linked list (no wasted space). The LinkedQueue uses the linked list implementation as described here.
1
2
3
4
5
6
7
8
9
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
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python
 
class Queue(object):
    def __init__(self):
        self.head = 0
        self.tail = 0
        self.n = 0
        self.l = []
     
    def enqueue(self, element):
        # this will create a lot of wasted space. Use something like
        # linked list
        self.l.append(element)
        self.tail += 1
        self.n += 1
     
    def dequeue(self):
        if self.n == 0: return None
        e = self.l[self.head]
        self.head += 1
        self.n -= 1
        return e
         
    def size(self):
        return self.n
     
    def elements(self):
        return [self.l[i] for i in xrange(self.head, self.tail)]
 
class LinkedQueue(object):
    def __init__(self):
        import linkedlist
        self.l = linkedlist.LinkedList()
     
    def enqueue(self, element):
        self.l.append(element)
     
    def dequeue(self):
        return self.l.front()
         
    def size(self):
        return self.l.size()
     
    def elements(self):
        return [x for x in self.l.elements()]
     
if __name__ == "__main__":
    q = Queue()
     
    assert None == q.dequeue()
     
    q.enqueue(1)
    q.enqueue(2)
    q.enqueue(3)
 
    assert 1 == q.dequeue()
    assert 2 == q.dequeue()
    assert 3 == q.dequeue()
 
    q.enqueue(1)
    q.enqueue(2)
    q.enqueue(3)
    q.enqueue(4)
    q.enqueue(5)
     
    assert 1 == q.dequeue()
    assert 2 == q.dequeue()
    assert 3 == q.dequeue()
    assert 4 == q.dequeue()
    assert 5 == q.dequeue()
     
    lq = LinkedQueue()
     
    assert None == lq.dequeue()
     
    lq.enqueue(1)
    lq.enqueue(2)
    lq.enqueue(3)
 
    assert 1 == lq.dequeue()
    assert 2 == lq.dequeue()
    assert 3 == lq.dequeue()
 
    lq.enqueue(1)
    lq.enqueue(2)
    lq.enqueue(3)
    lq.enqueue(4)
    lq.enqueue(5)
     
    assert 1 == lq.dequeue()
    assert 2 == lq.dequeue()
    assert 3 == lq.dequeue()
    assert 4 == lq.dequeue()
    assert 5 == lq.dequeue()

How to Implement Stack in Python

Below are my simple implementations of stack (LIFO) using array list (some wasted space) and linked list (no wasted space). The LinkedStack uses the linked list implementation as described here.
1
2
3
4
5
6
7
8
9
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
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python
 
class Stack(object):
    def __init__(self):
        self.l = []
        self.n = 0
         
    def push(self, element):
        if len(self.l) > self.n:
            self.l[self.n] = element
        else:
            self.l.append(element)
        self.n += 1
         
    def pop(self):
        if self.n == 0: return None
        self.n -= 1
        return self.l[self.n]
     
    def size(self):
        return self.n
     
    def elements(self):
        return [self.l[i] for i in xrange(0, self.n)]
 
class LinkedStack(object):
    def __init__(self):
        import linkedlist
        self.l = linkedlist.LinkedList()
         
    def push(self, element):
        self.l.append(element)
         
    def pop(self):
        return self.l.back()
     
    def size(self):
        return self.l.size()
     
    def elements(self):
        return [x for x in self.l.elements()]
         
if __name__ == "__main__":
    s = Stack()
 
    assert None == s.pop()
     
    s.push(1)
    s.push(2)
    s.push(3)
         
    assert 3 == s.pop()
    assert 2 == s.pop()
    assert 1 == s.pop()
     
    s.push(1)
    s.push(2)
    s.push(3)
    s.push(4)
    s.push(5)
     
    assert 5 == s.pop()
    assert 4 == s.pop()
    assert 3 == s.pop()
    assert 2 == s.pop()
    assert 1 == s.pop()
     
    ls = LinkedStack()
 
    assert None == ls.pop()
     
    ls.push(1)
    ls.push(2)
    ls.push(3)
         
    assert 3 == ls.pop()
    assert 2 == ls.pop()
    assert 1 == ls.pop()
     
    ls.push(1)
    ls.push(2)
    ls.push(3)
    ls.push(4)
    ls.push(5)
     
    assert 5 == ls.pop()
    assert 4 == ls.pop()
    assert 3 == ls.pop()
    assert 2 == ls.pop()
    assert 1 == ls.pop()

How to Implement Doubly Linked List in Python

This is my simple implementation of doubly linked list in Python.
1
2
3
4
5
6
7
8
9
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
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
#!/usr/bin/env python
 
class Node(object):
    def __init__(self):
        self.next = None
        self.previous = None
        self.element = None
     
class LinkedList(object):
    def __init__(self):
        self.n = 0
        self.last = Node()
        self.first = self.last
         
    def append(self, element):
        self.last.element = element
        self.last.next = Node()
        tmp = self.last
        self.last = self.last.next
        self.last.previous = tmp
        self.n += 1
     
    def front(self):
        if self.n == 0: return None
        e = self.first.element
        self.first = self.first.next
        self.n -= 1
        return e
         
    def back(self):
        if self.n == 0: return None
        e = self.last.previous.element
        self.last = self.last.previous
        self.last.next = Node()
        self.n -= 1
        return e
         
    def size(self):
        return self.n
     
    def elements(self):
        i = self.first
        while i.element:
            yield i.element
            i = i.next
         
if __name__ == "__main__":
    l = LinkedList()
     
    assert None == l.front()
    assert None == l.back()
     
    l.append(1)
    l.append(2)
    l.append(3)
     
    assert 1 == l.front()
    assert 2 == l.front()
    assert 3 == l.front()
 
    l.append(1)
    l.append(2)
    l.append(3)
     
    assert 3 == l.back()
    assert 2 == l.back()
    assert 1 == l.back()
 
    l.append(1)
    assert 1 == l.back()
     
    l.append(1)
    assert 1 == l.front()

How to Implement Priority Queue in Python

Below a simple implementation of priority queue using binary heap.
1
2
3
4
5
6
7
8
9
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
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env python
 
class PriorityQueue(object):
    def __init__(self, compare=cmp):
        self.pq = []
        self.n = 0
        self.compare = compare
         
    def insert(self, element):
        self.swim(element)
         
    def remove(self):
        if self.n == 0: return None
        e = self.pq[0]
        self.sink()
        return e
     
    def elements(self):
        return [self.pq[i] for i in xrange(0, self.n)]
         
    def swim(self, element):
        self.n += 1
        if len(self.pq) >= self.n:
            self.pq[self.n-1] = element
        else:
            self.pq.append(element)
         
        current_pos = self.n
        parent_pos = current_pos / 2
        # python uses 0-based index, hence always minus the position by 1
        while (self.compare(self.pq[current_pos-1], self.pq[parent_pos-1]) > 0
               and current_pos > 1):
            self.pq[current_pos-1], self.pq[parent_pos-1] = (self.pq[parent_pos-1],
                                                             self.pq[current_pos-1])
            current_pos = parent_pos
            parent_pos = current_pos / 2
         
    def sink(self):
        current_pos = 1
        # since it's a binary heap, a parent can only have max 2 children
        self.pq[current_pos-1] = self.pq[self.n-1]
        self.n -= 1
        child_pos = self.get_child_position(current_pos)
        if child_pos == -1: return
         
        while self.compare(self.pq[child_pos-1], self.pq[current_pos-1]) > 0:
            self.pq[child_pos-1], self.pq[current_pos-1] = (self.pq[current_pos-1],
                                                            self.pq[child_pos-1])
            current_pos = child_pos
            child_pos = self.get_child_position(current_pos)
            if child_pos == -1: break
     
    def get_child_position(self, current_pos):
        first_child_pos = 2 * current_pos
        second_child_pos = (2 * current_pos) + 1
        child_pos = -1 # no child
        # no child
        if first_child_pos > self.n: return child_pos
        # there's only one child
        if second_child_pos > self.n: child_pos = first_child_pos
        else: # there are two children
            if self.compare(self.pq[first_child_pos-1], self.pq[second_child_pos-1]) > 0:
                child_pos = first_child_pos
            else:
                child_pos = second_child_pos
        return child_pos
         
    def size(self):
        return self.n
     
def min_compare(x, y):
    if x < y: return 1
    elif x == y: return 0
    else: return -1
     
if __name__ == "__main__":
    pq = PriorityQueue()
    pq.insert(4)
    pq.insert(5)
    pq.insert(1)
    pq.insert(8)
    pq.insert(2)
    pq.insert(3)
    pq.insert(10)
    pq.insert(7)
    pq.insert(9)
    pq.insert(6)
     
    assert 10 == pq.remove()
    assert 9 == pq.remove()
    assert 8 == pq.remove()
    assert 7 == pq.remove()
    assert 6 == pq.remove()
    assert 5 == pq.remove()
    assert 4 == pq.remove()
    assert 3 == pq.remove()
    assert 2 == pq.remove()
    assert 1 == pq.remove()
 
    pq.insert(4)
    pq.insert(5)
    assert 5 == pq.remove()
    assert 4 == pq.remove()
 
    assert None == pq.remove()
     
    pq.insert(4)
    pq.insert(5)
    pq.insert(1)
    pq.insert(8)
    pq.insert(2)
    pq.insert(3)
    pq.insert(10)
    pq.insert(7)
    pq.insert(9)
    pq.insert(6)
     
    assert 10 == pq.remove()
    assert 9 == pq.remove()
    assert 8 == pq.remove()
    assert 7 == pq.remove()
    assert 6 == pq.remove()
    assert 5 == pq.remove()
    assert 4 == pq.remove()
    assert 3 == pq.remove()
    assert 2 == pq.remove()
    assert 1 == pq.remove()
     
    pq = PriorityQueue(min_compare)
    pq.insert(4)
    pq.insert(5)
    pq.insert(1)
    pq.insert(8)
    pq.insert(2)
    pq.insert(3)
    pq.insert(10)
    pq.insert(7)
    pq.insert(9)
    pq.insert(6)
     
    assert 1 == pq.remove()
    assert 2 == pq.remove()
    assert 3 == pq.remove()
    assert 4 == pq.remove()
    assert 5 == pq.remove()
    assert 6 == pq.remove()
    assert 7 == pq.remove()
    assert 8 == pq.remove()
    assert 9 == pq.remove()
    assert 10 == pq.remove()
     
    pq.insert(4)
    pq.insert(5)
    assert 4 == pq.remove()
    assert 5 == pq.remove()
 
    assert None == pq.remove()
     
    pq.insert(4)
    pq.insert(5)
    pq.insert(1)
    pq.insert(8)
    pq.insert(2)
    pq.insert(3)
    pq.insert(10)
    pq.insert(7)
    pq.insert(9)
    pq.insert(6)
     
    assert 1 == pq.remove()
    assert 2 == pq.remove()
    assert 3 == pq.remove()
    assert 4 == pq.remove()
    assert 5 == pq.remove()
    assert 6 == pq.remove()
    assert 7 == pq.remove()
    assert 8 == pq.remove()
    assert 9 == pq.remove()
    assert 10 == pq.remove()

Saturday, April 21, 2012

Sorting Algorithms in Python

Below are some popular sorting algorithms implemented in Python.
1
2
3
4
5
6
7
8
9
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
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/usr/bin/env python
 
class BubbleSort(object):
    @staticmethod
    def sort(l):
        new_list = list(l)
        while True:
            swapped = False
            for i in xrange(0, len(new_list)-1):
                if new_list[i] > new_list[i+1]:
                    new_list[i], new_list[i+1] = new_list[i+1], new_list[i]
                    swapped = True
            if not swapped: break
        return new_list
 
class SelectionSort(object):
    @staticmethod
    def sort(l):
        new_list = list(l)
        for i in xrange(0, len(new_list)):
            min_index = i
            for j in xrange(i, len(new_list)):
                if new_list[j] < new_list[min_index]:
                    min_index = j
            new_list[i], new_list[min_index] = new_list[min_index], new_list[i]
        return new_list
 
class InsertionSort(object):
    @staticmethod
    def sort(l):
        new_list = list(l)
        for i in xrange(1, len(new_list)):
            j = i
            while j > 0 and new_list[j] < new_list[j-1]:
                new_list[j-1], new_list[j] = new_list[j], new_list[j-1]
                j -= 1
        return new_list
 
class ShellSort(object):
    @staticmethod
    def sort(l):
        new_list = list(l)
        n = len(l)
        h = 1
        while h < (n/3): h = (3*h) + 1
        while h >= 1:
            for i in xrange(h, n):
                j = i
                while j >=h and new_list[j] < new_list[j-h]:
                    new_list[j], new_list[j-h] = new_list[j-h], new_list[j]
                    j -= h
            h /= 3
        return new_list
 
class MergeSort(object):
    @staticmethod
    def sort(l):
        new_list = list(l)
        MergeSort.msort(new_list, 0, len(new_list)-1)
        return new_list
     
    @staticmethod
    def msort(l, lo, hi):
        if lo == hi: return
        mi = (lo + hi) / 2
        MergeSort.msort(l, lo, mi)
        MergeSort.msort(l, mi + 1, hi)
        MergeSort.merge(l, lo, mi, hi)
     
    @staticmethod
    def merge(a, lo, mi, hi):
        i = lo
        j = mi + 1
        tmp = list(a)
        hi = hi + 1
        for x in xrange(lo, hi):
            if i > mi:
                a[x] = tmp[j]
                j += 1
            elif j >= hi:
                a[x] = tmp[i]
                i += 1
            elif tmp[i] < tmp[j]:
                a[x] = tmp[i]
                i += 1
            else:
                a[x] = tmp[j]
                j += 1
 
class QuickSort(object):
    @staticmethod
    def sort(l):
        new_list = list(l)
        import random
        random.shuffle(new_list)
        QuickSort.qsort(new_list, 0, len(new_list)-1)
        return new_list
     
    @staticmethod
    def qsort(l, lo, hi):
        if hi <= lo: return
        j = QuickSort.partition(l, lo, hi)
        QuickSort.qsort(l, lo, j-1)
        QuickSort.qsort(l, j+1, hi)
     
    @staticmethod
    def partition(l, lo, hi):
        i = lo
        j = hi + 1
        v = l[lo]
        while True:
            i += 1
            while l[i] < v:
                if i == hi: break
                i += 1
            j -= 1
            while v < l[j]:
                if j == lo: break
                j -= 1
            if i >= j: break
            l[i], l[j] = l[j], l[i]
        l[lo], l[j] = l[j], l[lo]
        return j
 
class HeapSort(object):
    @staticmethod
    def sort(l):
        new_list = list(l)
        n = len(new_list)
        # construct a binary heap
        for i in xrange(n/2, 0, -1):
            HeapSort.sink(new_list, i, n)
        # sort down the heap
        for i in xrange(n, 0, -1):
            new_list[i-1], new_list[0] = new_list[0], new_list[i-1]
            HeapSort.sink(new_list, 1, i-1)
        return new_list
     
    @staticmethod
    def sink(l, current_pos, n):
        child_pos = HeapSort.get_child_position(l, current_pos, n)
        if child_pos == -1: return
             
        while l[child_pos-1] > l[current_pos-1]:
            l[child_pos-1], l[current_pos-1] = l[current_pos-1], l[child_pos-1]
            current_pos = child_pos
            child_pos = HeapSort.get_child_position(l, current_pos, n)
            if child_pos == -1: break
             
    @staticmethod
    def get_child_position(l, current_pos, n):
        first_child_pos = 2 * current_pos
        second_child_pos = (2 * current_pos) + 1
        child_pos = -1 # no child
        # no child
        if first_child_pos > n: return child_pos
        # there's only one child
        if second_child_pos > n: child_pos = first_child_pos
        else: # there are two children
            if l[first_child_pos-1] > l[second_child_pos-1]:
                child_pos = first_child_pos
            else:
                child_pos = second_child_pos
        return child_pos
     
if __name__ == "__main__":
   expected_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   input_list = [9, 3, 6, 5, 7, 1, 8, 10, 2, 4]
 
   sorted_list = BubbleSort.sort(input_list)
   assert sorted_list == expected_list
 
   sorted_list = SelectionSort.sort(input_list)
   assert sorted_list == expected_list
 
   sorted_list = InsertionSort.sort(input_list)
   assert sorted_list == expected_list
 
   sorted_list = ShellSort.sort(input_list)
   assert sorted_list == expected_list
    
   sorted_list = MergeSort.sort(input_list)
   assert sorted_list == expected_list
 
   sorted_list = QuickSort.sort(input_list)
   assert sorted_list == expected_list
    
   sorted_list = HeapSort.sort(input_list)
   assert sorted_list == expected_list

Friday, April 6, 2012

How to Resolve Circular Dependencies in C++

Having circular dependencies in C++ can cause the compiler to complain about having a type that wasn't declared. The solution is simple, that is to forward declare the class. But knowing such problem exists and how to resolve it can save a lot of time debugging. Let's consider this scenario below. A needs B and B needs A.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef A_H_
#define A_H_
 
class B; // forward declare B
 
class A {
public:
    A(B* b);
    void trigger();
    void execute();
    virtual ~A();
 
private:
    B* bptr;
};
#endif /* A_H_ */
In class A, we forward declare B. If we didn't forward declare B, we would get compilation error. The only catch for using forward declaration is the B must be a pointer type.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "A.h" // make sure to include A
#include "B.h"
#include <iostream>
using namespace std;
 
A::A(B* b) : bptr(b) {
}
 
void A::trigger() {
    bptr->executeA(this);
}
 
void A::execute() {
    cout << "Hello" << endl;
}
 
A::~A() {
}
Since we forward declare B in A.h header file, we need to include the actual B header file.
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef B_H_
#define B_H_
 
#include "A.h"
 
class B {
public:
    B();
    void executeA(A* a);
    virtual ~B();
};
 
#endif /* B_H_ */
1
2
3
4
5
6
7
8
9
10
11
#include "B.h"
 
B::B() {
}
 
void B::executeA(A* a) {
    a->execute();
}
 
B::~B() {
}
1
2
3
4
5
6
7
8
9
#include "A.h"
#include "B.h"
using namespace std;
 
int main() {
    B b;
    A a(&b);
    a.trigger();
}