思维导图:
代码示例:
# include <iostream>
using namespace std;
int divide ( int x, int y) {
if ( y== 0 )
throw x;
return x/ y;
}
int main ( ) {
try
{
cout<< " 5/2 = " << divide ( 5 , 2 ) << endl;
cout<< " 6/0 = " << divide ( 6 , 0 ) << endl;
cout<< " 7/3 = " << divide ( 7 , 3 ) << endl;
}
catch ( int e)
{
cout << e << " is divided by zero !!!" << endl;
}
cout << " That is ook. " << endl;
system ( "pause" ) ;
return 0 ;
}
# include <iostream>
# include <string>
using namespace std;
class MyException {
public :
MyException ( const string & message) : message ( message) { }
~ MyException ( ) { }
const string & getMessage ( ) const { return message; }
private :
string message;
} ;
class Demo {
public :
Demo ( ) { cout << "Constructor of Demo" << endl; }
~ Demo ( ) { cout << "Destructor of Demo" << endl; }
} ;
void func ( ) throw ( MyException) {
Demo d;
cout << "Throw MyException in func()" << endl;
throw MyException ( "exception thrown by func()" ) ;
}
int main ( ) {
cout << "In main function" << endl;
try {
func ( ) ;
} catch ( MyException& e) {
cout << "Caught an exception: " << e. getMessage ( ) << endl;
}
cout << "Resume the execution of main()" << endl;
return 0 ;
}
# include <iostream>
# include <cmath>
# include <stdexcept>
using namespace std;
double area ( double a, double b, double c) {
if ( a <= 0 || b <= 0 || c <= 0 )
throw invalid_argument ( "the side length should be positive" ) ;
if ( a + b <= c || b + c <= a || c + a <= b)
throw invalid_argument ( "the side length should fit the triangle inequality" ) ;
double s = ( a + b + c) / 2 ;
return sqrt ( s * ( s - a) * ( s - b) * ( s - c) ) ;
}
int main ( ) {
double a, b, c;
cout << "Please input the side lengths of a triangle: " ;
cin >> a >> b >> c;
try {
double s = area ( a, b, c) ;
cout << "Area: " << s << endl;
} catch ( exception & e) {
cout << "Error: " << e. what ( ) << endl;
}
system ( "pause" ) ;
return 0 ;
}
# include <iostream>
using namespace std;
class CException
{
public :
CException ( ) { }
virtual ~ CException ( ) { }
void Reason ( ) { cout << "CException" << endl; }
} ;
void fn1 ( )
{
throw CException ( ) ;
}
int main ( )
{
try {
fn1 ( ) ;
} catch ( CException& ce) {
ce. Reason ( ) ;
}
system ( "pause" ) ;
return 0 ;
}
# ifndef __DATE_H__
# define __DATE_H__
# include <iostream>
class Date {
private :
int year;
int month;
int day;
int totalDays;
public :
Date ( int year = 1 , int month = 1 , int day = 1 ) ;
int getYear ( ) const { return year; }
int getMonth ( ) const { return month; }
int getDay ( ) const { return day; }
int getMaxDay ( ) const ;
bool isLeapYear ( ) const {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ;
}
int operator - ( const Date& date) const {
return totalDays - date. totalDays;
}
bool operator < ( const Date& date) const {
return totalDays < date. totalDays;
}
} ;
std:: istream & operator >> ( std:: istream & in, Date & date) ;
std:: ostream & operator << ( std:: ostream & out, const Date & date) ;
# endif
# ifndef __DATE_H__
# define __DATE_H__
# include <iostream>
class Date {
private :
int year;
int month;
int day;
int totalDays;
public :
Date ( int year = 1 , int month = 1 , int day = 1 ) ;
int getYear ( ) const { return year; }
int getMonth ( ) const { return month; }
int getDay ( ) const { return day; }
int getMaxDay ( ) const ;
bool isLeapYear ( ) const {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ;
}
int operator - ( const Date& date) const {
return totalDays - date. totalDays;
}
bool operator < ( const Date& date) const {
return totalDays < date. totalDays;
}
} ;
std:: istream & operator >> ( std:: istream & in, Date & date) ;
std:: ostream & operator << ( std:: ostream & out, const Date & date) ;
# endif
# include "date.h"
# include <iostream>
# include <stdexcept>
using namespace std;
namespace {
const int DAYS_BEFORE_MONTH[ ] = { 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 , 365 } ;
}
Date :: Date ( int year, int month, int day) : year ( year) , month ( month) , day ( day) {
if ( day <= 0 || day > getMaxDay ( ) )
throw runtime_error ( "Invalid date" ) ;
int years = year - 1 ;
totalDays = years * 365 + years / 4 - years / 100 + years / 400
+ DAYS_BEFORE_MONTH[ month - 1 ] + day;
if ( isLeapYear ( ) && month > 2 ) totalDays++ ;
}
int Date :: getMaxDay ( ) const {
if ( isLeapYear ( ) && month == 2 )
return 29 ;
else
return DAYS_BEFORE_MONTH[ month] - DAYS_BEFORE_MONTH[ month - 1 ] ;
}
istream & operator >> ( istream & in, Date & date) {
int year, month, day;
char c1, c2;
in >> year >> c1 >> month >> c2 >> day;
if ( c1 != '-' || c2 != '-' )
throw runtime_error ( "Bad time format" ) ;
date = Date ( year, month, day) ;
return in;
}
ostream & operator << ( ostream & out, const Date & date) {
out << date. getYear ( ) << "-" << date. getMonth ( ) << "-" << date. getDay ( ) ;
return out;
}
# ifndef __ACCUMULATOR_H__
# define __ACCUMULATOR_H__
# include "date.h"
class Accumulator {
private :
Date lastDate;
double value;
double sum;
public :
Accumulator ( const Date & date, double value)
: lastDate ( date) , value ( value) , sum ( 0 ) { }
double getSum ( const Date & date) const {
return sum + value * ( date - lastDate) ;
}
void change ( const Date & date, double value) {
sum = getSum ( date) ;
lastDate = date;
this -> value = value;
}
void reset ( const Date & date, double value) {
lastDate = date;
this -> value = value;
sum = 0 ;
}
} ;
# endif
# ifndef __ACCOUNT_H__
# define __ACCOUNT_H__
# include "date.h"
# include "accumulator.h"
# include <string>
# include <map>
# include <istream>
# include <stdexcept>
class Account ;
class AccountRecord {
private :
Date date;
const Account * account;
double amount;
double balance;
std:: string desc;
public :
AccountRecord ( const Date & date, const Account * account, double amount, double balance, const std:: string& desc) ;
void show ( ) const ;
} ;
typedef std:: multimap< Date, AccountRecord> RecordMap;
class Account {
private :
std:: string id;
double balance;
static double total;
static RecordMap recordMap;
protected :
Account ( const Date & date, const std:: string & id) ;
void record ( const Date & date, double amount, const std:: string & desc) ;
void error ( const std:: string & msg) const ;
public :
const std:: string & getId ( ) const { return id; }
double getBalance ( ) const { return balance; }
static double getTotal ( ) { return total; }
virtual void deposit ( const Date & date, double amount, const std:: string & desc) = 0 ;
virtual void withdraw ( const Date & date, double amount, const std:: string & desc) = 0 ;
virtual void settle ( const Date & date) = 0 ;
virtual void show ( std:: ostream & out) const ;
static void query ( const Date& begin, const Date& end) ;
} ;
inline std:: ostream & operator << ( std:: ostream & out, const Account & account) {
account. show ( out) ;
return out;
}
class SavingsAccount : public Account {
private :
Accumulator acc;
double rate;
public :
SavingsAccount ( const Date & date, const std:: string & id, double rate) ;
double getRate ( ) const { return rate; }
virtual void deposit ( const Date & date, double amount, const std:: string & desc) ;
virtual void withdraw ( const Date & date, double amount, const std:: string & desc) ;
virtual void settle ( const Date & date) ;
} ;
class CreditAccount : public Account {
private :
Accumulator acc;
double credit;
double rate;
double fee;
double getDebt ( ) const {
double balance = getBalance ( ) ;
return ( balance < 0 ? balance : 0 ) ;
}
public :
CreditAccount ( const Date & date, const std:: string & id, double credit, double rate, double fee) ;
double getCredit ( ) const { return credit; }
double getRate ( ) const { return rate; }
double getFee ( ) const { return fee; }
double getAvailableCredit ( ) const {
if ( getBalance ( ) < 0 )
return credit + getBalance ( ) ;
else
return credit;
}
virtual void deposit ( const Date & date, double amount, const std:: string & desc) ;
virtual void withdraw ( const Date & date, double amount, const std:: string & desc) ;
virtual void settle ( const Date & date) ;
virtual void show ( std:: ostream & out) const ;
} ;
class AccountException : public std:: runtime_error {
private :
const Account * account;
public :
AccountException ( const Account * account, const std:: string & msg)
: runtime_error ( msg) , account ( account) { }
const Account * getAccount ( ) const { return account; }
} ;
# endif
# include "account.h"
# include <cmath>
# include <iostream>
# include <utility>
using namespace std;
using namespace std:: rel_ops;
AccountRecord :: AccountRecord ( const Date & date, const Account * account, double amount, double balance, const std:: string& desc)
: date ( date) , account ( account) , amount ( amount) , balance ( balance) , desc ( desc) { }
void AccountRecord :: show ( ) const {
cout << date << "\t#" << account-> getId ( ) << "\t" << amount << "\t" << balance << "\t" << desc << endl;
}
double Account:: total = 0 ;
RecordMap Account:: recordMap;
Account :: Account ( const Date & date, const string & id)
: id ( id) , balance ( 0 ) {
cout << date << "\t#" << id << " created" << endl;
}
void Account :: record ( const Date & date, double amount, const string & desc) {
amount = floor ( amount * 100 + 0.5 ) / 100 ;
balance += amount;
total += amount;
AccountRecord record ( date, this , amount, balance, desc) ;
recordMap. insert ( make_pair ( date, record) ) ;
record. show ( ) ;
}
void Account :: show ( ostream & out) const {
out << id << "\tBalance: " << balance;
}
void Account :: error ( const string & msg) const {
throw AccountException ( this , msg) ;
}
void Account :: query ( const Date& begin, const Date& end) {
if ( begin <= end) {
RecordMap:: iterator iter1 = recordMap. lower_bound ( begin) ;
RecordMap:: iterator iter2 = recordMap. upper_bound ( end) ;
for ( RecordMap:: iterator iter = iter1; iter != iter2; ++ iter)
iter-> second. show ( ) ;
}
}
SavingsAccount :: SavingsAccount ( const Date & date, const string & id, double rate)
: Account ( date, id) , rate ( rate) , acc ( date, 0 ) { }
void SavingsAccount :: deposit ( const Date & date, double amount, const string & desc) {
record ( date, amount, desc) ;
acc. change ( date, getBalance ( ) ) ;
}
void SavingsAccount :: withdraw ( const Date & date, double amount, const string & desc) {
if ( amount > getBalance ( ) ) {
error ( "not enough money" ) ;
} else {
record ( date, - amount, desc) ;
acc. change ( date, getBalance ( ) ) ;
}
}
void SavingsAccount :: settle ( const Date & date) {
if ( date. getMonth ( ) == 1 ) {
double interest = acc. getSum ( date) * rate
/ ( date - Date ( date. getYear ( ) - 1 , 1 , 1 ) ) ;
if ( interest != 0 )
record ( date, interest, " interest" ) ;
acc. reset ( date, getBalance ( ) ) ;
}
}
CreditAccount :: CreditAccount ( const Date& date, const string& id, double credit, double rate, double fee)
: Account ( date, id) , credit ( credit) , rate ( rate) , fee ( fee) , acc ( date, 0 ) { }
void CreditAccount :: deposit ( const Date & date, double amount, const string & desc) {
record ( date, amount, desc) ;
acc. change ( date, getDebt ( ) ) ;
}
void CreditAccount :: withdraw ( const Date & date, double amount, const string & desc) {
if ( amount - getBalance ( ) > credit) {
error ( "not enough credit" ) ;
} else {
record ( date, - amount, desc) ;
acc. change ( date, getDebt ( ) ) ;
}
}
void CreditAccount :: settle ( const Date & date) {
double interest = acc. getSum ( date) * rate;
if ( interest != 0 )
record ( date, interest, " interest" ) ;
if ( date. getMonth ( ) == 1 )
record ( date, - fee, " annual fee" ) ;
acc. reset ( date, getDebt ( ) ) ;
}
void CreditAccount :: show ( ostream & out) const {
Account :: show ( out) ;
out << "\tAvailable credit:" << getAvailableCredit ( ) ;
}
# include "account.h"
# include <iostream>
# include <fstream>
# include <sstream>
# include <vector>
# include <algorithm>
# include <string>
using namespace std;
struct deleter {
template < class T > void operator ( ) ( T* p) { delete p; }
} ;
class Controller {
private :
Date date;
vector< Account * > accounts;
bool end;
public :
Controller ( const Date & date) : date ( date) , end ( false ) { }
~ Controller ( ) ;
const Date & getDate ( ) const { return date; }
bool isEnd ( ) const { return end; }
bool runCommand ( const string & cmdLine) ;
} ;
Controller :: ~ Controller ( ) {
for_each ( accounts. begin ( ) , accounts. end ( ) , deleter ( ) ) ;
}
bool Controller :: runCommand ( const string & cmdLine) {
istringstream str ( cmdLine) ;
char cmd, type;
int index, day;
double amount, credit, rate, fee;
string id, desc;
Account* account;
Date date1, date2;
str >> cmd;
switch ( cmd) {
case 'a' :
str >> type >> id;
if ( type == 's' ) {
str >> rate;
account = new SavingsAccount ( date, id, rate) ;
} else {
str >> credit >> rate >> fee;
account = new CreditAccount ( date, id, credit, rate, fee) ;
}
accounts. push_back ( account) ;
return true ;
case 'd' :
str >> index >> amount;
getline ( str, desc) ;
accounts[ index] -> deposit ( date, amount, desc) ;
return true ;
case 'w' :
str >> index >> amount;
getline ( str, desc) ;
accounts[ index] -> withdraw ( date, amount, desc) ;
return true ;
case 's' :
for ( size_t i = 0 ; i < accounts. size ( ) ; i++ )
cout << "[" << i << "] " << * accounts[ i] << endl;
return false ;
case 'c' :
str >> day;
if ( day < date. getDay ( ) )
cout << "You cannot specify a previous day" ;
else if ( day > date. getMaxDay ( ) )
cout << "Invalid day" ;
else
date = Date ( date. getYear ( ) , date. getMonth ( ) , day) ;
return true ;
case 'n' :
if ( date. getMonth ( ) == 12 )
date = Date ( date. getYear ( ) + 1 , 1 , 1 ) ;
else
date = Date ( date. getYear ( ) , date. getMonth ( ) + 1 , 1 ) ;
for ( vector< Account* > :: iterator iter = accounts. begin ( ) ; iter != accounts. end ( ) ; ++ iter)
( * iter) -> settle ( date) ;
return true ;
case 'q' :
str >> date1 >> date2;
Account :: query ( date1, date2) ;
return false ;
case 'e' :
end = true ;
return false ;
}
cout << "Inavlid command: " << cmdLine << endl;
return false ;
}
int main ( ) {
Date date ( 2008 , 11 , 1 ) ;
Controller controller ( date) ;
string cmdLine;
const char * FILE_NAME = "commands.txt" ;
ifstream fileIn ( FILE_NAME) ;
if ( fileIn) {
while ( getline ( fileIn, cmdLine) ) {
try {
controller. runCommand ( cmdLine) ;
} catch ( exception & e) {
cout << "Bad line in " << FILE_NAME << ": " << cmdLine << endl;
cout << "Error: " << e. what ( ) << endl;
return 1 ;
}
}
fileIn. close ( ) ;
}
ofstream fileOut ( FILE_NAME, ios_base:: app) ;
cout << "(a)add account (d)deposit (w)withdraw (s)show (c)change day (n)next month (q)query (e)exit" << endl;
while ( ! controller. isEnd ( ) ) {
cout << controller. getDate ( ) << "\tTotal: " << Account :: getTotal ( ) << "\tcommand> " ;
string cmdLine;
getline ( cin, cmdLine) ;
try {
if ( controller. runCommand ( cmdLine) )
fileOut << cmdLine << endl;
} catch ( AccountException & e) {
cout << "Error(#" << e. getAccount ( ) -> getId ( ) << "): " << e. what ( ) << endl;
} catch ( exception & e) {
cout << "Error: " << e. what ( ) << endl;
}
}
return 0 ;
}