📄 ch07.htm
字号:
<TT>39: }</TT><TT>40: </TT><TT>41: CORBA::Float SavingsAccountImpl::balance() {</TT><TT>42: </TT><TT>43: return myAccount.balance();</TT><TT>44: }</TT><TT>45: </TT><TT>46: CustomerList* SavingsAccountImpl::getCustomers() {</TT><TT>47: </TT><TT>48: return myAccount.getCustomers();</TT><TT>49: }</TT><TT>50: </TT><TT>51: CORBA::Float SavingsAccountImpl::withdraw(CORBA::Float amount)</TT><B><TT>52:</TT></B><TT> <B>throw (InvalidAmountException, InsufficientFundsException)</B></TT><TT>53: {</TT><TT>54: </TT><TT>55: return myAccount.withdraw(amount);</TT><TT>56: }</TT><TT>57: </TT><B><TT>58:</TT></B><TT> CORBA::Float SavingsAccountImpl::deposit(CORBA::Float amount) <B>throw</B></TT><B><TT>59:</TT></B><TT> <B>(InvalidAmountException) </B>{</TT><TT>60: </TT><TT>61: return myAccount.deposit(amount);</TT><TT>62: }</TT><TT>63: </TT><TT>64: CORBA::Float SavingsAccountImpl::interestRate() {</TT><TT>65: </TT><TT>66: return myInterestRate;</TT><TT>67: }</TT><TT>68: </TT><B><TT>69:</TT></B><TT> CORBA::Float SavingsAccountImpl::setInterestRate(CORBA::Float rate) <B>throw</B></TT><B><TT>70:</TT></B><TT> <B>(InvalidAmountException)</B> {</TT><B><TT>71:</TT></B><TT> </TT><B><TT>72:</TT></B><TT> <B>// Disallow negative interest rates and throw an exception if this is</B></TT><B><TT>73:</TT></B><TT> <B>// attempted.</B></TT><B><TT>74:</TT></B><TT> <B>if (rate < 0.0) {</B></TT><B><TT>75:</TT></B><TT> </TT><B><TT>76:</TT></B><TT> <B>throw InvalidAmountException();</B></TT><B><TT>77:</TT></B><TT> <B>}</B></TT><TT>78: </TT><TT>79: CORBA::Float oldInterestRate = myInterestRate;</TT><TT>80: </TT><TT>81: myInterestRate = rate;</TT><TT>82: </TT><TT>83: return oldInterestRate;84: }</TT> </FONT></PRE><P>The changes in the <TT>withdraw()</TT> and <TT>deposit()</TT> methods in <TT>SavingsAccountImpl</TT>copy their counterparts in <TT>CheckingAccountImpl</TT> exactly. In addition, the<TT>setInterestRate()</TT> method is modified to disallow negative interest rates(which would correspond to a savings account that loses money over time). If a clientattempts to set a negative interest rate for the <TT>SavingsAccount</TT>, an <TT>InvalidAmountException</TT>is thrown.<H3><A NAME="Heading14"></A><FONT COLOR="#000077">BankImpl</FONT></H3><P>The final server component to modify is the <TT>BankImpl</TT> itself. Only a singlemethod, <TT>deleteAccount()</TT>, is modified to throw an exception. The modified<TT>BankImpl.h</TT> and <TT>BankImpl.cpp</TT> appear in Listings 7.22 and 7.23.<H4><FONT COLOR="#000077">Listing 7.22. Modified BankImpl.h.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankImpl.h</TT><TT> 2: </TT><TT> 3: #ifndef BankImpl_h</TT><TT> 4: #define BankImpl_h</TT><TT> 5: </TT><TT> 6: #include <vector></TT><TT> 7: </TT><TT> 8: #include "../Bank_s.h"</TT><TT> 9: </TT><TT>10: class BankImpl : public _sk_Bank {</TT><TT>11: </TT><TT>12: public:</TT><TT>13: </TT><TT>14: // Constructor.</TT><TT>15: //</TT><TT>16: // name - This Bank's name.</TT><TT>17: BankImpl(const char* name);</TT><TT>18: </TT><TT>19: // Destructor.</TT><TT>20: ~BankImpl();</TT><TT>21: </TT><TT>22: // These methods are described in Bank.idl.</TT><TT>23: virtual char* name();</TT><TT>24: virtual void name(const char* val);</TT><TT>25: virtual char* address();</TT><TT>26: virtual void address(const char* val);</TT><TT>27: virtual Account_ptr createAccount(Customer_ptr customer,</TT><TT>28: const char* accountType, CORBA::Float openingBalance);</TT><B><TT>29:</TT></B><TT> virtual void deleteAccount(Account_ptr account) <B>throw</B></TT><B><TT>30:</TT></B><TT> <B>(InvalidAccountException);</B></TT><TT>31: virtual AccountList* getAccounts();</TT><TT>32: </TT><TT>33: protected:</TT><TT>34: </TT><TT>35: // Return the next available account number. The result is</TT><TT>36: // returned in a static buffer.</TT><TT>37: char* getNextAccountNumber();</TT><TT>38: </TT><TT>39: // Return the current date in the form "Mmm DD YYYY". The result</TT><TT>40: // is returned in a static buffer.</TT><TT>41: char* getCurrentDate();</TT><TT>42: </TT><TT>43: private:</TT><TT>44: </TT><TT>45: // Default constructor.</TT><TT>46: BankImpl();</TT><TT>47: </TT><TT>48: // This Bank's name.</TT><TT>49: char* myName;</TT><TT>50: </TT><TT>51: // This Bank's address.</TT><TT>52: char* myAddress;</TT><TT>53: </TT><TT>54: // This Bank's Accounts.</TT><TT>55: std::vector<Account_ptr> myAccounts;</TT><TT>56: </TT><TT>57: // The next available account number.</TT><TT>58: unsigned int myNextAccountNumber;</TT><TT>59: };60: 61: #endif</TT></FONT></PRE><H4><FONT COLOR="#000077">Listing 7.23. Modified BankImpl.cpp.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankImpl.cpp</TT><TT> 2: </TT><TT> 3: #include "BankImpl.h"</TT><TT> 4: </TT><TT> 5: #include <time.h></TT><TT> 6: #include <string.h></TT><TT> 7: #include <iostream.h></TT><TT> 8: #include <algorithm></TT><TT> 9: #include <functional></TT><TT> 10: </TT><TT> 11: #include "SavingsAccountImpl.h"</TT><TT> 12: #include "CheckingAccountImpl.h"</TT><TT> 13: </TT><TT> 14: extern CORBA::BOA_var boa;</TT><TT> 15: </TT><TT> 16: // STL-derived unary function which returns TRUE if Accounts are</TT><TT> 17: // equal.</TT><TT> 18: class IsAccountEqual : public std::unary_function<Account_ptr,</TT><TT> 19: bool> {</TT><TT> 20: public:</TT><TT> 21: IsAccountEqual(argument_type account) { myAccount = account; }</TT><TT> 22: result_type operator()(argument_type account) { return account-></TT><TT> 23: _is_equivalent(myAccount) != 0; }</TT><TT> 24: private:</TT><TT> 25: argument_type myAccount;</TT><TT> 26: };</TT><TT> 27: </TT><TT> 28: // Constructor.</TT><TT> 29: //</TT><TT> 30: // name - This Bank's name.</TT><TT> 31: BankImpl::BankImpl(const char* name) : _sk_Bank(name), myAccounts(),</TT><TT> 32: myName(strdup(name)), myAddress(strdup("123 Elm Street, "</TT><TT> 33: "Anywhere USA 12345")), myNextAccountNumber(0) {</TT><TT> 34: </TT><TT> 35: }</TT><TT> 36: </TT><TT> 37: // Default constructor.</TT><TT> 38: BankImpl::BankImpl() : myAccounts(), myName(NULL), myAddress(NULL),</TT><TT> 39: myNextAccountNumber(0) {</TT><TT> 40: </TT><TT> 41: }</TT><TT> 42: </TT><TT> 43: // Destructor.</TT><TT> 44: BankImpl::~BankImpl() {</TT><TT> 45: </TT><TT> 46: cout << "Bank \"" << name() << "\" being destroyed." << endl;</TT><TT> 47: free(myName);</TT><TT> 48: free(myAddress);</TT><TT> 49: }</TT><TT> 50: </TT><TT> 51: char* BankImpl::name() {</TT><TT> 52: </TT><TT> 53: return CORBA::strdup(myName);</TT><TT> 54: }</TT><TT> 55: </TT><TT> 56: void BankImpl::name(const char* val) {</TT><TT> 57: </TT><TT> 58: free(myName);</TT><TT> 59: myName = strdup(val);</TT><TT> 60: }</TT><TT> 61: </TT><TT> 62: char* BankImpl::address() {</TT><TT> 63: </TT><TT> 64: return CORBA::strdup(myAddress);</TT><TT> 65: }</TT><TT> 66: </TT><TT> 67: void BankImpl::address(const char* val) {</TT><TT> 68: </TT><TT> 69: free(myAddress);</TT><TT> 70: myAddress = strdup(val);</TT><TT> 71: }</TT><TT> 72: </TT><TT> 73: Account_ptr BankImpl::createAccount(Customer_ptr customer,</TT><TT> 74: const char* accountType, CORBA::Float openingBalance) {</TT><TT> 75: </TT><TT> 76: Account_ptr newAccount;</TT><TT> 77: </TT><TT> 78: if (strcmp(accountType, "savings") == 0) {</TT><TT> 79: </TT><TT> 80: // Create a new SavingsAccountImpl object for the Account.</TT><TT> 81: cout << "BankImpl: Creating new SavingsAccount for "</TT><TT> 82: "Customer " << customer->name() << "." << endl;</TT><TT> 83: newAccount = new SavingsAccountImpl(getNextAccountNumber(),</TT><TT> 84: getCurrentDate(), openingBalance, customer, 10.0);</TT><TT> 85: } else if (strcmp(accountType, "checking") == 0) {</TT><TT> 86: </TT><TT> 87: // Create a new CheckingAccountImpl object for the Account.</TT><TT> 88: cout << "BankImpl: Creating new CheckingAccount for "</TT><TT> 89: "Customer " << customer->name() << "." << endl;</TT><TT> 90: newAccount = new CheckingAccountImpl(getNextAccountNumber(),</TT><TT> 91: getCurrentDate(), openingBalance, customer);</TT><TT> 92: } else {</TT><TT> 93: </TT><TT> 94: // Invalid Account type; do nothing.</TT><TT> 95: cout << "BankImpl: Customer " << customer->name() <<</TT><TT> 96: " requested invalid Account type \"" << accountType</TT><TT> 97: << "\"." << endl;</TT><TT> 98: return Account::_nil();</TT><TT> 99: }</TT><TT>100: </TT><TT>101: // Add the created Account at the end of the list and return it.</TT><TT>102: ::boa->obj_is_ready(newAccount);</TT><TT>103: myAccounts.push_back(Account::_duplicate(newAccount));</TT><TT>104: return newAccount;</TT><TT>105: }</TT><TT>106: </TT><B><TT>107:</TT></B><TT> void BankImpl::deleteAccount(Account_ptr account) <B>throw</B></TT><B><TT>108:</TT></B><TT> <B>(InvalidAccountException)</B> {</TT><TT>109: </TT><TT>110: std::vector<Account_ptr>::iterator first = myAccounts.begin();</TT><TT>111: std::vector<Account_ptr>::iterator last = myAccounts.end();</TT><TT>112: IsAccountEqual predicate(account);</TT><TT>113: </TT><TT>114: std::vector<Account_ptr>::iterator matchedAccount = std::</TT><TT>115: find_if(first, last, predicate);</TT><TT>116: if (matchedAccount == last) {</TT><TT>117: </TT><B><TT>118:</TT></B><TT> <B>// Invalid Account; throw an exception.</B></TT><B><TT>119:</TT></B><TT> <B>cout << "BankImpl: Attempted to delete invalid Account." <<</B></TT><B><TT>120:</TT></B><TT> <B>endl;</B></TT><B><TT>121:</TT></B><TT> <B>throw InvalidAccountException();</B></TT><B><TT>122:</TT></B><TT> <B>}</B></TT><TT>123: cout << "BankImpl: Deleting Account \"" << account-></TT><TT>124: accountNumber() << "\"." << endl;</TT><TT>125: </TT><TT>126: // Delete the given Account.</TT><TT>127: myAccounts.erase(matchedAccount);</TT><TT>128: account->_release();</TT><TT>129: }</TT><TT>130: </TT><TT>131: AccountList* BankImpl::getAccounts() {</TT><TT>132: </TT><TT>133: AccountList* list = new AccountList(myAccounts.size());</TT><TT>134: CORBA::Long i;</TT><TT>135: </TT><TT>136: for (i = 0; i < myAccounts.size(); i++) {</TT><TT>137: (*list)[i] = Account::_duplicate(myAccounts[i]);</TT><TT>138: }</TT><TT>139: </TT><TT>140: return list;</TT><TT>141: }</TT><TT>142: </TT><TT>143: // Return the next available account number. The result is returned</TT><TT>144: // in a static buffer.</TT><TT>145: char* BankImpl::getNextAccountNumber() {</TT><TT>146: </TT><TT>147: static char accountNumber[16] = "Account ";</TT><TT>148: </TT><TT>149: sprintf(accountNumber + 7, "%08u", myNextAccountNumber++);</TT><TT>150: </TT><TT>151: return accountNumber;</TT><TT>152: }</TT><TT>153: </TT><TT>154: // Return the current date in the form "Mmm DD YYYY". The result is</TT><TT>155: // returned in a static buffer.</TT><TT>156: char* BankImpl::getCurrentDate() {</TT><TT>157: </TT><TT>158: static char currentDate[12] = " ";</TT><TT>159: </TT><TT>160: time_t ltime;</TT><TT>161: time(&ltime);</TT><TT>162: char* ctimeResult = ctime(&ltime);</TT><TT>163: </TT><TT>164: memcpy(currentDate, ctimeResult + 4, 3);</TT><TT>165: memcpy(currentDate + 4, ctimeResult + 8, 2);</TT><TT>166: memcpy(currentDate + 7, ctimeResult + 20, 4);</TT><TT>167: </TT><TT>168: return currentDate;169: }</TT> </FONT></PRE><P>The logic in <TT>deleteAccount()</TT> is identical to tha
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -