1
+ #include < iostream>
2
+ #include < string>
3
+ #include < vector>
4
+ using namespace std ;
5
+
6
+ struct BankAccount
7
+ {
8
+ int balance = 0 ;
9
+ int overdraft_limit = -500 ;
10
+
11
+ void deposit (int amount)
12
+ {
13
+ balance += amount;
14
+ cout << " deposited " << amount << " , balance now " << balance << " \n " ;
15
+ }
16
+
17
+ void withdraw (int amount)
18
+ {
19
+ if (balance - amount >= overdraft_limit)
20
+ {
21
+ balance -= amount;
22
+ cout << " withdrew " << amount << " , balance now " << balance << " \n " ;
23
+ }
24
+ }
25
+ };
26
+
27
+ struct Command
28
+ {
29
+ virtual ~Command () = default ;
30
+ virtual void call () const = 0;
31
+ virtual void undo () const = 0;
32
+ };
33
+
34
+ // should really be BankAccountCommand
35
+ struct BankAccountCommand : Command
36
+ {
37
+ BankAccount &account;
38
+ enum Action
39
+ {
40
+ deposit,
41
+ withdraw
42
+ } action;
43
+ int amount;
44
+
45
+ BankAccountCommand (BankAccount &account,
46
+ const Action action, const int amount)
47
+ : account(account), action(action), amount(amount) {}
48
+
49
+ void call () const override
50
+ {
51
+ switch (action)
52
+ {
53
+ case deposit:
54
+ account.deposit (amount);
55
+ break ;
56
+ case withdraw:
57
+ account.withdraw (amount);
58
+ break ;
59
+ default :
60
+ break ;
61
+ }
62
+ }
63
+
64
+ void undo () const override
65
+ {
66
+ switch (action)
67
+ {
68
+ case withdraw:
69
+ account.deposit (amount);
70
+ break ;
71
+ case deposit:
72
+ account.withdraw (amount);
73
+ break ;
74
+ default :
75
+ break ;
76
+ }
77
+ }
78
+ };
79
+
80
+ // vector doesn't have virtual dtor, but who cares?
81
+ struct CompositeBankAccountCommand
82
+ : vector<BankAccountCommand>,
83
+ Command
84
+ {
85
+ CompositeBankAccountCommand (const initializer_list<value_type> &items)
86
+ : vector<BankAccountCommand>(items) {}
87
+
88
+ void call () const override
89
+ {
90
+ for (auto &cmd : *this )
91
+ cmd.call ();
92
+ }
93
+
94
+ void undo () const override
95
+ {
96
+ for (auto &cmd : *this )
97
+ cmd.undo ();
98
+ }
99
+ };
100
+
101
+ int main ()
102
+ {
103
+ BankAccount ba;
104
+ /* vector<BankAccountCommand> commands{*/
105
+ CompositeBankAccountCommand commands{
106
+ BankAccountCommand{ba, BankAccountCommand::deposit, 100 },
107
+ BankAccountCommand{ba, BankAccountCommand::withdraw, 200 }};
108
+
109
+ cout << ba.balance << endl;
110
+
111
+ // apply all the commands
112
+ /* for (auto& cmd : commands)
113
+ {
114
+ cmd.call();
115
+ }*/
116
+ commands.call ();
117
+
118
+ cout << ba.balance << endl;
119
+
120
+ /* for_each(commands.rbegin(), commands.rend(),
121
+ [](const BankAccountCommand& cmd) { cmd.undo(); });*/
122
+ commands.undo ();
123
+
124
+ cout << ba.balance << endl;
125
+
126
+ getchar ();
127
+ return 0 ;
128
+ }
0 commit comments