实验5 继承和多态

任务3

pets.hpp

 1 #include<iostream>
 2 #include<string>
 3 
 4 using std::cout;
 5 using std::endl;
 6 using std::string;
 7 
 8 class MachinePets {
 9     public:
10         MachinePets(const string &s ="");
11         
12     public:
13         string get_nickname() const;
14         virtual string talk() const =0;
15     private:
16         string nickname;
17 };
18 
19 MachinePets::MachinePets(const string &s):nickname(s){
20 }
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 
35 PetCats::PetCats(const string &s):MachinePets(s){
36 }
37 
38 string PetCats::talk() const {
39     string jiao="miao";
40     return jiao;
41 }
42 
43 class PetDogs:public MachinePets {
44     public:
45         PetDogs(const string &s ="");
46         
47     public:
48         string talk() const override;
49 
50 };
51 
52 PetDogs::PetDogs(const string &s):MachinePets(s){
53 }
54 
55 string PetDogs::talk() const {
56     string jiao="wang";
57     return jiao;
58 }
View Code

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 }
View Code

运行结果

 

 

任务4

film.hpp

 1 #include<iostream>
 2 #include<string>
 3 #include<iomanip>
 4 
 5 using std::string;
 6 using std::ostream;
 7 using std::istream;
 8 using std::endl;
 9 using std::setw;
10 using std::left;
11 
12 class Film{
13     public:
14         Film(const string &name="",const string &director="",const string &region="",const int &year=0);
15         friend istream& operator>>(istream &in,Film &film);
16         friend ostream& operator<<(ostream &out,const Film &film);
17         int get_year() const;
18     private:
19         string name;
20         string director;
21         string region;
22         int year;
23 };
24 
25 Film::Film(const string &name,const string &director,const string &region,const int &year){
26 }
27 
28 istream& operator>>(istream &in,Film &film){
29     in>>film.name>>film.director>>film.region>>film.year;
30     return in;
31 }
32 
33 ostream& operator<<(ostream &out,const Film &film){
34     out<<left;
35     out<<setw(15)<<film.name<<setw(15)<<film.director<<setw(15)<<film.region<<setw(15)<<film.year<<endl;
36     return out;
37 }
38 
39 int Film::get_year() const{
40     return year;
41 }
42 
43 bool compare_by_year(const Film &f1,const Film &f2){
44     return f1.get_year()>f2.get_year();
45 }
View Code

task4.cpp

 1 #include "film.hpp"
 2 #include <iostream>
 3 #include <string>
 4 #include <vector>
 5 #include <algorithm>
 6 
 7 void test() {
 8     using namespace std;
 9     
10     int n;
11     cout << "输入电影数目: ";
12     cin >> n;
13 
14     cout << "录入" << n << "部影片信息" << endl;
15     vector<Film> film_lst;
16     for(int i = 0; i < n; ++i) {
17         Film f;
18         cout << string(20, '-') << "" << i+1 << "部影片录入" << string(20, '-') << endl;
19         cin >> f;
20         film_lst.push_back(f);
21     }
22 
23     // 按发行年份升序排序
24     sort(film_lst.begin(), film_lst.end(), compare_by_year);
25 
26     cout << string(20, '=') + "电影信息(按发行年份)" +  string(20, '=')<< endl;
27     for(auto &f: film_lst)
28         cout << f << endl;
29 }
30 
31 int main() {
32     test();
33 }
View Code

运行结果

 

 

任务5

 Complex.hpp

 1 #ifndef COMPLEX_HPP  
 2 #define COMPLEX_HPP  
 3 
 4 #include <iostream>  
 5 
 6 using std::istream;
 7 using std::ostream;
 8 
 9 template <typename T>  
10 class Complex {  
11 private:  
12     T real;  
13     T imag;  
14 
15 public:  
16     // 默认  
17     Complex(T r = 0, T i = 0) : real(r), imag(i) {}  
18 
19     // 复制  
20     Complex(const Complex<T>& other) : real(other.real), imag(other.imag) {}  
21 
22     // +重载 
23     Complex<T> operator+(const Complex<T>& other) const {  
24         return Complex<T>(real + other.real, imag + other.imag);  
25     }  
26 
27     // +=重载 
28     Complex<T>& operator+=(const Complex<T>& other) {  
29         real += other.real;  
30         imag += other.imag;  
31         return *this;  
32     }  
33 
34     // ==重载 
35     bool operator==(const Complex<T>& other) const {  
36         return real == other.real && imag == other.imag;  
37     }  
38 
39     // 得到实部  
40     T get_real() const {  
41         return real;  
42     }  
43 
44     // 得到虚部  
45     T get_imag() const {  
46         return imag;  
47     }  
48 
49     // 输出重载  
50     friend ostream& operator<<(ostream& os, const Complex<T>& c) {  
51         os << c.real;  
52         if (c.imag >= 0) {  
53             os << " + " << c.imag << "i";  
54         } else {  
55             os << " - " << -c.imag << "i";  
56         }  
57         return os;  
58     }  
59 
60     // 输入重载  
61     friend istream& operator>>(istream& is, Complex<T>& c) {  
62         is >> c.real >>c.imag; 
63         return is;  
64     }  
65 };  
66 
67 #endif 
View Code

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 }
View Code

运行结果

 

 

任务6

 8_8.cpp

 1 #include"account.h""
 2 #include<iostream>
 3 using namespace std;
 4 int main()
 5 {
 6     Date date(2008,11,1);
 7     SavingsAccount sa1(date,"s3755271",0.015);
 8     SavingsAccount sa2(date,"02342342",0.015);
 9     CreditAccount ca(date,"C5392394",10000,0.0005,50);
10     Account *accounts[]={&sa1,&sa2,&ca};
11     const int n=sizeof(accounts)/sizeof(Account *);
12     cout<<"(d)deposit (w)withdraw (s) show (c) change day (n) next month (e) exit"<<endl;
13     char cmd;
14     do{
15         date.show();
16         cout<<"\tTotal:"<<Account::getTotal()<<"\tcommand>";
17         int index,day;
18         double amount;
19         string desc;
20         cin>>cmd;
21         switch(cmd){
22             case 'd':
23                 cin>>index>>amount;
24                 getline(cin,desc);
25                 accounts[index]->deposit(date,amount,desc);
26                 break;
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                 {
35                     cout<<"["<<i<<"]";
36                     accounts[i]->show();
37                     cout<<endl;
38                 }
39                 break;
40             case 'c':
41                 cin>>day;
42                 if(day<date.getDay())
43                     cout<<"You cannot specify a previous day";
44                 else if(day>date.getDay())
45                     cout<<"Invalid day";
46                 else
47                     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
53                     date=Date(date.getYear(),date.getMonth()+1,1);
54                 for(int i=0;i<n;i++)
55                 {
56                     accounts[i]->settle(date);        
57                 }
58                 break;    
59         }
60     }while(cmd!='e');
61     return 0;
62 }
View Code

date.h

 1 #ifndef __DATE_H__
 2 #define __DATE_H__
 3 class Date{
 4     private:
 5         int year;
 6         int month;
 7         int day;
 8         int totalDays;
 9     public:
10         Date(int year,int month,int day);
11         int getYear() const {return year;}
12         int getMonth() const {return month;}
13         int getDay() const {return day;}
14         int getMaxDay() const;
15         bool isLeapYear() const {
16             return year%4==0 && year%100 !=0 ||year%400==0;
17         }
18         void show() const;
19         
20         int operator-(const Date& date) const {
21             return totalDays-date.totalDays;
22         }
23 };
24 #endif //__DATE_H__
View Code

date.cpp

 1 #include "date.h"
 2 #include <iostream>
 3 #include <cstdlib>
 4 using namespace std;
 5 namespace {
 6     const int DAYS_BEFORE_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+DAYS_BEFORE_MONTH[month-1]+day;
17     if(isLeapYear()&&month>2) totalDays++;
18 }
19 
20 int Date::getMaxDay() const {
21     if(isLeapYear()&&month==2)
22         return 29;
23     else
24         return DAYS_BEFORE_MONTH[month]-DAYS_BEFORE_MONTH[month-1];
25 }
26 
27 void Date::show()  const {
28     cout<<getYear()<<"-"<<getMonth()<<"-"<<getDay();
29 }
View Code

account.h

 1 #ifndef  ACCOUNT H
 2 #define  ACCOUNT H
 3 #include"date.h"
 4 #include"accumulator.h"
 5 #include<string>
 6 class Account {
 7 private:
 8     std::string id;
 9     double balance;
10     static double total;
11 protected:
12     Account(const Date& date, const std::string& id);
13     void record(const Date& date, double amount, const std::string& desc);
14     void error(const std::string& msg)const;
15 public:
16     const std::string& getId()const { return id; }
17     double getBalance()const { return balance; }
18     static double getTotal() { return total; }
19     
20     virtual void deposit(const Date& date, double amount, const std::string& desc)=0;
21     virtual void withdraw(const Date& date, double amount, const std::string& desc)=0;
22     virtual void settle(const Date& date)=0;
23 
24     virtual void show()const;
25 };
26 class SavingsAccount :public Account {
27 private:
28     Accumulator acc;
29     double rate;
30 public:
31     SavingsAccount(const Date& date, const std::string& id, double rate);
32     double getRate()const { return rate; }
33     void deposit(const Date& date, double amount, const std::string& desc);
34     void withdraw(const Date& date, double amount, const std::string& desc);
35     void settle(const Date& date);
36     
37 };
38 class CreditAccount :public Account {
39 private:
40     Accumulator acc;
41     double credit;
42     double rate;
43     double fee;
44     double getDebt()const {
45         double balance = getBalance();
46         return (balance < 0 ? balance : 0);
47     }
48 public:
49     CreditAccount(const Date& date, const std::string& id, double credit, double rate, double fee);
50     double getCredit()const { return credit; }
51     double getRate()const { return rate; }
52     double getAvailableCredit()const {
53         if (getBalance() < 0)
54             return credit + getBalance();
55         else
56             return credit;
57     }
58     void deposit(const Date& date, double amount, const std::string& desc);
59     void withdraw(const Date& date, double amount, const std::string& desc);
60     void settle(const Date& date);
61     void show()const;
62 };
63 #endif//ACCOUNT H
View Code

account.cpp

 1 #include"account.h"
 2 #include<cmath>
 3 #include<iostream>
 4 using namespace std;
 5 double Account::total = 0;
 6 
 7 Account::Account(const Date& date, const string& id) :id{ id }, balance{ 0 } {
 8     date.show(); cout << "\t#" << id << "created" << endl;
 9 }
10 
11 
12 void Account::record(const Date& date, double amount, const string& desc) {
13     amount = floor(amount * 100 + 0.5) / 100;
14     balance += amount;
15     total += amount;
16     date.show();
17     cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl;
18 }
19 
20 void Account::show()const { cout << id << "\tBalance:" << balance; }
21 void Account::error(const string& msg)const {
22     cout << "Error(#" << id << "):" << msg << endl;
23 }
24 
25 SavingsAccount::SavingsAccount(const Date& date, const string& id, double rate) :Account(date, id), rate(rate), acc(date, 0) {}
26 
27 void SavingsAccount::deposit(const Date& date, double amount, const string& desc) {
28     record(date, amount, desc);
29     acc.change(date, getBalance());
30 }
31 
32 void SavingsAccount::withdraw(const Date& date, double amount, const string& desc) {
33     if (amount > getBalance()) {
34         error("not enough money");
35     }
36     else {
37         record(date, -amount, desc);
38         acc.change(date, getBalance());
39     }
40 }
41 
42 void SavingsAccount::settle(const Date& date) {
43     double interest = acc.getSum(date) * rate / (date-Date(date.getYear() - 1, 1, 1));
44     if (interest != 0)record(date, interest, "interest");
45     acc.reset(date, getBalance());
46 }
47 
48 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) {}
49 
50 void CreditAccount::deposit(const Date& date, double amount, const string& desc) {
51     record(date, amount, desc);
52     acc.change(date, getDebt());
53 }
54 
55 void CreditAccount::withdraw(const Date& date, double amount, const string& desc) {
56     if (amount - getBalance() > credit) {
57         error("not enough credit");
58     }
59     else {
60         record(date, -amount, desc);
61         acc.change(date, getDebt());
62     }
63 }
64 
65 void CreditAccount::settle(const Date& date) {
66     double interest = acc.getSum(date) * rate;
67     if (interest != 0)record(date, interest, "interest");
68     if (date.getMonth() == 1)
69         record(date, -fee, "annual fee");
70     acc.reset(date, getDebt());
71 }
72 
73 void CreditAccount::show()const {
74     Account::show();
75     cout << "\tAvailable credit:" << getAvailableCredit();
76 }
View Code

accumulator.h

 1 #ifndef  ACCUMULATOR H
 2 #define  ACCUMULATOR H
 3 #include"date.h"
 4 class Accumulator {
 5 private:
 6     Date lastDate;
 7     double value;
 8     double sum;
 9 public:
10     Accumulator(const Date& date, double value) :lastDate(date), value(value), sum{ 0 } {
11     }
12 
13     double getSum(const Date& date)const {
14         return sum + value * (date-lastDate);
15     }
16 
17     void change(const Date& date, double value) {
18         sum = getSum(date);
19         lastDate = date; this->value = value;
20     }
21 
22     void reset(const Date& date, double value) {
23         lastDate = date; this->value = value; sum = 0;
24     }
25 };
26 #endif//ACCUMULATOR H
View Code

运行结果

 改进:重载了-运算符,使书写更加简便易懂;使用虚函数,实现运行时多态,使程序更安全;

改善:用户的输入窗口有待美化,使输入更加便捷直观;数据的展示方式可以采用更整齐的排版;数据的存储和访问方式可以改进以提高运行效率。

 

posted @ 2024-12-03 17:22  shorekeeper  阅读(5)  评论(0编辑  收藏  举报