实验任务3:
实验代码:
pets.hpp:
1 #pragma once 2 3 #include <iostream> 4 #include <string> 5 6 using namespace std; 7 8 class MachinePets { 9 public: 10 MachinePets(const string &s = ""); 11 string get_nickname() const; 12 13 public: 14 virtual string talk() const = 0; 15 16 protected: 17 string nickname; 18 }; 19 20 MachinePets::MachinePets(const string &s) : nickname{s} {} 21 22 string MachinePets::get_nickname() const { 23 return nickname; 24 } 25 26 class PetCats: public MachinePets{ 27 public: 28 PetCats(const string &s = ""); 29 30 public: 31 string talk() const override; 32 }; 33 34 PetCats::PetCats(const string &s) : MachinePets{s} {} 35 36 string PetCats::talk() const { 37 return "miao wu~"; 38 } 39 40 class PetDogs: public MachinePets{ 41 public: 42 PetDogs(const string &s = ""); 43 44 public: 45 string talk() const override; 46 }; 47 48 PetDogs::PetDogs(const string &s) : MachinePets{s} {} 49 50 string PetDogs::talk() const { 51 return "wang wang~"; 52 }
task3.cpp:
1 #include <iostream> 2 #include <vector> 3 #include "pets.hpp" 4 5 void test() { 6 using namespace std; 7 8 vector<MachinePets *> pets; 9 10 pets.push_back(new PetCats("miku")); 11 pets.push_back(new PetDogs("da huang")); 12 13 for(auto &ptr: pets) 14 cout <<ptr->get_nickname() << " says " << ptr->talk() << endl; 15 } 16 17 int main() { 18 test(); 19 }
实验截图:
实验任务4:
实验代码:
film.hpp:
1 #pragma once 2 3 #include <iostream> 4 #include <string> 5 #include <iomanip> 6 7 using namespace std; 8 9 class Film { 10 public: 11 Film(const string &name = " ", const string &director = " ", const string ®ion = " ", const string &year = " "); 12 string get_year() const; 13 friend ostream& operator<<(ostream &out, const Film &film); 14 friend istream& operator>>(ostream &in, Film &film); 15 public: 16 string name; 17 string director; 18 string region; 19 string year; 20 }; 21 22 Film::Film(const string &name, const string &director, const string ®ion, const string &year) { 23 this->name = name; 24 this->director = director; 25 this->region = region; 26 this->year = year; 27 } 28 29 string Film::get_year() const { 30 return year; 31 } 32 33 ostream& operator<<(ostream &out, const Film &film) { 34 out << left; 35 out << setw(15) << "片名:" << film.name << endl 36 << setw(15) << "导演:" << film.director << endl 37 << setw(15) << "地区:" << film.region << endl 38 << setw(15) << "年份:" << film.year << endl; 39 40 return out; 41 } 42 43 istream& operator>>(istream &in, Film &film) { 44 cout << "录入片名:"; 45 in >> film.name; 46 cout << "录入导演:"; 47 in >> film.director; 48 cout << "录入制片国家/地区:"; 49 in >> film.region; 50 cout << "录入上映年份:"; 51 in >> film.year; 52 return in; 53 }
task4.cpp:
1 #pragma once 2 3 #include <iostream> 4 #include <string> 5 #include <iomanip> 6 7 using namespace std; 8 9 class Film { 10 public: 11 Film(const string &name = " ", const string &director = " ", const string ®ion = " ", const string &year = " "); 12 string get_year() const; 13 friend ostream& operator<<(ostream &out, const Film &film); 14 friend istream& operator>>(ostream &in, Film &film); 15 public: 16 string name; 17 string director; 18 string region; 19 string year; 20 }; 21 22 Film::Film(const string &name, const string &director, const string ®ion, const string &year) { 23 this->name = name; 24 this->director = director; 25 this->region = region; 26 this->year = year; 27 } 28 29 string Film::get_year() const { 30 return year; 31 } 32 33 ostream& operator<<(ostream &out, const Film &film) { 34 out << left; 35 out << setw(15) << "片名:" << film.name << endl 36 << setw(15) << "导演:" << film.director << endl 37 << setw(15) << "地区:" << film.region << endl 38 << setw(15) << "年份:" << film.year << endl; 39 40 return out; 41 } 42 43 istream& operator>>(istream &in, Film &film) { 44 cout << "录入片名:"; 45 in >> film.name; 46 cout << "录入导演:"; 47 in >> film.director; 48 cout << "录入制片国家/地区:"; 49 in >> film.region; 50 cout << "录入上映年份:"; 51 in >> film.year; 52 return in; 53 }
实验截图:
实验任务5:
实验代码:
Complex.hpp:
1 #pragma once 2 3 #include <iostream> 4 using namespace std; 5 6 template <typename T> 7 class Complex { 8 public: 9 Complex(const T& r = 0, const T& i = 0): real{r}, imag{i} {} 10 Complex operator+=(const Complex& c) { 11 real += c.real; 12 imag += c.imag; 13 return *this; 14 } 15 friend Complex operator+(const Complex& c1, const Complex& c2) { 16 return Complex<T>(c1.real + c2.real, c1.imag + c2.imag); 17 } 18 friend bool operator==(const Complex& c1, const Complex& c2) { 19 return c1.real == c2.real && c1.imag == c2.imag; 20 } 21 friend ostream& operator<<(ostream& out, const Complex& c) { 22 if(c.imag >= 0) 23 out << c.real << " + " << c.imag << "i"; 24 else 25 out << c.real << " - " << -c.imag << "i"; 26 return out; 27 } 28 friend istream& operator>>(istream& in, Complex& c) { 29 in >> c.real >> c.imag; 30 return in; 31 } 32 T get_real() const { 33 return real; 34 } 35 T get_imag() const { 36 return imag; 37 } 38 private: 39 T real; 40 T imag; 41 };
task5.cpp:
1 #include "Complex.hpp" 2 #include <iostream> 3 4 using std::cin; 5 using std::cout; 6 using std::endl; 7 using std::boolalpha; 8 9 void test1() { 10 Complex<int> c1(2, -5), c2(c1); 11 12 cout << "c1 = " << c1 << endl; 13 cout << "c2 = " << c2 << endl; 14 cout << "c1 + c2 = " << c1 + c2 << endl; 15 16 c1 += c2; 17 cout << "c1 = " << c1 << endl; 18 cout << boolalpha << (c1 == c2) << endl; 19 } 20 21 void test2() { 22 Complex<double> c1, c2; 23 cout << "Enter c1 and c2: "; 24 cin >> c1 >> c2; 25 cout << "c1 = " << c1 << endl; 26 cout << "c2 = " << c2 << endl; 27 28 cout << "c1.real = " << c1.get_real() << endl; 29 cout << "c1.imag = " << c1.get_imag() << endl; 30 } 31 32 int main() { 33 cout << "自定义类模板Complex测试1: " << endl; 34 test1(); 35 36 cout << endl; 37 38 cout << "自定义类模板Complex测试2: " << endl; 39 test2(); 40 }
实验截图:
实验任务6:
实验代码:
date.hpp:
1 date.hpp: 2 class Date { 3 private: 4 int year, month, day, totalDays; 5 public: 6 Date(int year, int month, int day); 7 int getYear() const {return year;} 8 int getMonth() const {return month;} 9 int getDay() const {return day;} 10 int getMaxDay() const; 11 bool isLeapYear() const { 12 return year%4==0&&year%100!=0||year%400==0; 13 } 14 void show() const; 15 int operator-(const Date& date) const { 16 return totalDays-date.totalDays; 17 } 18 };
date.cpp:
1 #include "date.hpp" 2 #include<iostream> 3 #include<cstdlib> 4 using namespace std; 5 namespace { 6 const int DAYS_BEFIRE_MONTH[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; 7 } 8 Date::Date(int year, int month, int day) :year(year), month(month), day(day) { 9 if (day <= 0 || day > getMaxDay()) { 10 cout << "Invalid date: "; 11 show(); 12 cout << endl; 13 exit(1); 14 } 15 int years = year - 1; 16 totalDays = years * 365 + years / 4 - years / 100 + years / 400 17 + DAYS_BEFIRE_MONTH[month - 1] + day; 18 if (isLeapYear() && month > 2) totalDays++; 19 } 20 int Date::getMaxDay()const { 21 if (isLeapYear() &&month == 2) 22 return 29; 23 else 24 return DAYS_BEFIRE_MONTH[month] - DAYS_BEFIRE_MONTH[month - 1]; 25 } 26 void Date::show()const { 27 cout << getYear() << "-" << getMonth() << "-" << getDay(); 28 }
accumulator.hpp:
1 #include "date.hpp" 2 class Accumulator { 3 private: 4 Date lastDate; 5 double value; 6 double sum; 7 public: 8 double getSum(const Date &date) const { 9 return sum+value*(date-lastDate); 10 } 11 }
account.hpp:
1 #include"date.hpp" 2 #include"accumulator.hpp" 3 #include<string> 4 5 class Account{ 6 private: 7 std::string id; 8 double balance; 9 static double total; 10 protected: 11 Account(const Date &date, const std::string &id); 12 void record(const Date &date, double amount, const std::string &desc); 13 void error(const std::string &msg) const; 14 public: 15 const std::string &getId() const {return id;} 16 double getBalance() const {return balance;} 17 static double getTotal() {return total;} 18 virtual void deposit(const Date &date, double amount, const std::string &desc) = 0; 19 virtual void withdraw(const Date &date, double amount, const std::string &desc) = 0; 20 virtual void settle(const Date &date) = 0; 21 virtual void show() const; 22 } 23 class SavingsAccount :public Account { 24 private: 25 Accumulator acc; 26 double rate; 27 public: 28 SavingsAccount(const Date& date, const string& id, double rate); 29 double getRate() const { return rate; } 30 void deposit(const Date& date, double amount, const string& desc); 31 void withdraw(const Date& date, double amount, const string& desc); 32 void settle(const Date& date); 33 }; 34 class CreditAccount :public Account { 35 private: 36 Accumulator acc; 37 double credit; 38 double rate; 39 double fee; 40 double getDebt()const { 41 double balance = getBalance(); 42 return(balance < 0 ? balance : 0); 43 } 44 public:CreditAccount(const Date& date, const string& id, double credit, double rate, double fee); 45 double getCredit()const { return credit; } 46 double getRate()const { return rate; } 47 double getFee() const { return fee; } 48 double getAvailableCredit()const { 49 if (getBalance() < 0)return credit + getBalance(); 50 else return credit; 51 } 52 void deposit(const Date& date, double amount, const string& desc); 53 void withdraw(const Date& date, double amount, const string& desc); 54 void settle(const Date& date); 55 void show()const; 56 };
account.cpp:
1 #include "account.hpp" 2 #include <cmath> 3 #include<iostream> 4 using namespace std; 5 double Account::total = 0; 6 Account::Account(const Date& date, const string& id) :id(id), balance(0) { 7 date.show(); 8 cout << "\t#" << id << "created" << endl; 9 } 10 void Account::record(const Date& date, double amount, const string& desc) { 11 amount = floor(amount * 100 + 0.5) / 100; 12 balance += amount; 13 total += amount; 14 date.show(); 15 cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl; 16 } 17 void Account::show()const { cout << id << "\tBalance:" << balance; } 18 void Account::error(const string& msg)const { 19 cout << "Error(#" << id << "):" << msg << endl; 20 } 21 SavingsAccount::SavingsAccount(const Date& date, const string& id, double rate) :Account(date, id), rate(rate), acc(date, 0) {} 22 void SavingsAccount::deposit(const Date& date, double amount, const string& desc) { 23 record(date, amount, desc); 24 acc.change(date, getBalance()); 25 } 26 void SavingsAccount::withdraw(const Date& date, double amount, const string& desc) { 27 if (amount > getBalance()) { 28 error("not enough money"); 29 } 30 else { 31 record(date, -amount, desc); 32 acc.change(date, getBalance()); 33 } 34 } 35 void SavingsAccount::settle(const Date& date) { 36 double interest = acc.getSum(date) * rate / (date-Date(date.getYear() - 1, 1, 1)); 37 if (interest != 0)record(date, interest, "interest"); 38 acc.reset(date, getBalance()); 39 } 40 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) {} 41 void CreditAccount::deposit(const Date& date, double amount, const string& desc) { 42 record(date, amount, desc); 43 acc.change(date, getDebt()); 44 } 45 void CreditAccount::withdraw(const Date& date, double amount, const string& desc) { 46 if (amount - getBalance() > credit) { 47 error("not enouogh credit"); 48 } 49 else { 50 record(date, -amount, desc); 51 acc.change(date, getDebt()); 52 } 53 } 54 void CreditAccount::settle(const Date& date) { 55 double interest = acc.getSum(date) * rate; 56 if (interest != 0) record(date, interest, "interest"); 57 if (date.getMonth() == 1)record(date, -fee, "annual fee"); 58 acc.reset(date, getDebt()); 59 } 60 void CreditAccount::show()const { 61 Account::show(); 62 cout << "\tAvailable credit:" << getAvailableCredit(); 63 }
task6.cpp:
1 #include"account.hpp" 2 #include<iostream> 3 using namespace std; 4 int main() { 5 Date date(2008, 11, 1); 6 SavingsAccount sa1(date, "S3755217", 0.015); 7 SavingsAccount sa2(date, "02342342", 0.015); 8 CreditAccount ca(date, "C5392394", 10000, 0.0005, 50); 9 Account* accounts[] = { &sa1,&sa2,&ca }; 10 const int n = sizeof(accounts) / sizeof(Account*); 11 cout << "(d)deposit (w)withdraw (s)show (c)change day (n)next month (e)exit" << endl; 12 char cmd; 13 do { 14 date.show(); 15 cout << "\tTotal:" << Account::getTotal() << "\tcommand>"; 16 int index, day; 17 double amount; 18 string desc; 19 cin >> cmd; 20 switch (cmd) { 21 case 'd': 22 cin >> index >> amount; 23 getline(cin, desc); 24 accounts[index]->deposit(date, amount, desc); 25 break; 26 27 case 'w': 28 cin >> index >> amount; 29 getline(cin, desc); 30 accounts[index]->withdraw(date, amount, desc); 31 break; 32 case 's': 33 for (int i = 0; i < n; i++) { 34 cout << "[" << i << "]"; 35 accounts[i]->show(); 36 cout << endl; 37 } 38 break; 39 40 case 'c': 41 cin >> day; 42 if (day < date.getDay()) { 43 cout << "You cannot specify a previous day"; 44 } 45 else if (day > date.getMaxDay()) 46 cout << "Invalid day"; 47 else date = Date(date.getYear(), date.getMonth(), day); 48 break; 49 case 'n': 50 if (date.getMonth() == 12) 51 date = Date(date.getYear() + 1, 1, 1); 52 else date = Date(date.getYear(), date.getMonth() + 1, 1); 53 for (int i = 0; i < n; i++) { 54 accounts[i]->settle(date); 55 } 56 break; 57 } 58 } while (cmd != 'e'); 59 return 0; 60 }
实验截图:
改进:在基类Account中将账户的公共操作皆声明为虚函数,因此可以通过基类的指针来执行各种操作,因而各种类型的账户对象都可以通过一个基类指针的数组访问,使得可以通过同意的方式来操作各个账户,从cin输入所需执行的操作变得非常方便。
不足:将几个账户的构造在程序中写死了,不允许用户随时动态添加新的账户。