实验五 继承和多态

实验任务1:

(1)代码部分:

  1 #pragma once
  2 
  3 #include <iostream>
  4 #include <string>
  5 
  6 using std::cout;
  7 using std::endl;
  8 using std::string;
  9 
 10 // 发行/出版物类:Publisher (抽象类)
 11 class Publisher {
 12 public:
 13     Publisher(const string &s = "");            // 构造函数
 14 
 15 public:
 16     virtual void publish() const = 0;                 // 纯虚函数,作为接口继承
 17     virtual void use() const = 0;                     // 纯虚函数,作为接口继承
 18 
 19 protected:
 20     string name;    // 发行/出版物名称
 21 };
 22 
 23 Publisher::Publisher(const string &s): name {s} {
 24 }
 25 
 26 
 27 // 图书类: Book
 28 class Book: public Publisher {
 29 public:
 30     Book(const string &s = "", const string &a = "");  // 构造函数
 31 
 32 public:
 33     void publish() const override;        // 接口
 34     void use() const override;            // 接口
 35 
 36 private:
 37     string author;          // 作者
 38 };
 39 
 40 Book::Book(const string &s, const string &a): Publisher{s}, author{a} {
 41 }
 42 
 43 void Book::publish() const {
 44     cout << "Publishing book: 《" << name << "》 by " << author << endl;
 45 }
 46 
 47 void Book::use() const {
 48     cout << "Reading book: " << name << " by " << author << endl;
 49 }
 50 
 51 
 52 // 电影类: Film
 53 class Film: public Publisher {
 54 public:
 55     Film(const string &s = "", const string &d = "");   // 构造函数
 56 
 57 public:
 58     void publish() const override;    // 接口
 59     void use() const override;        // 接口            
 60 
 61 private:
 62     string director;        // 导演
 63 };
 64 
 65 Film::Film(const string &s, const string &d): Publisher{s}, director{d} {
 66 }
 67 
 68 void Film::publish() const {
 69     cout << "Publishing film: <" << name << "> directed by " << director << endl;
 70 }
 71 
 72 void Film::use() const {
 73     cout << "Watching film: " << name << " directed by " << director << endl;
 74 }
 75 
 76 
 77 // 音乐类:Music
 78 class Music: public Publisher {
 79 public:
 80     Music(const string &s = "", const string &a = "");
 81 
 82 public:
 83     void publish() const override;        // 接口
 84     void use() const override;            // 接口
 85 
 86 private:
 87     string artist;      // 音乐艺术家名称
 88 };
 89 
 90 Music::Music(const string &s, const string &a): Publisher{s}, artist{a} {
 91 }
 92 
 93 void Music::publish() const {
 94     cout << "Publishing music <" << name << "> by " << artist << endl;
 95 }
 96 
 97 void Music::use() const {
 98     cout << "Listening to music: " << name << " by " << artist << endl;
 99 }
100 #include "publisher.hpp"
101 #include <vector>
102 #include <typeinfo>
103 
104 using std::vector;
105 
106 void test() {
107    vector<Publisher *> v;
108 
109    v.push_back(new Book("Harry Potter", "J.K. Rowling"));
110    v.push_back(new Film("The Godfather", "Francis Ford Coppola"));
111    v.push_back(new Music("Blowing in the wind", "Bob Dylan"));
112 
113    for(auto &ptr: v) {
114         cout << "pointer type: " << typeid(ptr).name() << endl;  // 输出指针类型
115         cout << "RTTI type: " << typeid(*ptr).name() << endl;    // 输出指针指向的对象类型
116         ptr->publish();
117         ptr->use();
118         cout << endl;
119    }
120 }
121 
122 int main() {
123     test();
124 }
View Code

 

(2)运行结果:

 

 

 

实验任务2:

(1)代码部分:

  1 #pragma once
  2 
  3 #include <string>
  4 #include <iostream>
  5 #include <iomanip>
  6 
  7 using std::string;
  8 using std::ostream;
  9 using std::endl;
 10 using std::setw;
 11 using std::left;
 12 
 13 class Book {
 14 public:
 15     Book(const string &name, const string &author, const string &translator, const string &isbn, float price);
 16 
 17     friend ostream& operator<<(ostream &out, const Book &book);
 18 
 19 private:
 20     string name;        // 书名
 21     string author;      // 作者
 22     string translator;  // 译者
 23     string isbn;        // isbn号
 24     float price;        // 定价
 25 };
 26 
 27 // 成员函数实现
 28 Book::Book(const string &name, const string &author, const string &translator, const string &isbn, float price) {
 29     this->name = name;
 30     this->author = author;
 31     this->translator = translator;
 32     this->isbn = isbn;
 33     this->price = price;
 34 }
 35 
 36 // 友元实现
 37 ostream& operator<<(ostream &out, const Book &book) {
 38     out << left;
 39     out << setw(15) << "书名:" << book.name << endl
 40         << setw(15) << "作者:" << book.author << endl
 41         << setw(15) << "译者:" << book.translator << endl
 42         << setw(15) << "ISBN:" << book.isbn << endl
 43         << setw(15) << "定价:" << book.price;
 44 
 45     return out;
 46 }
 47 #pragma once
 48 
 49 #include "book.hpp"
 50 #include <iostream>
 51 #include <string>
 52 #include <iomanip>
 53 
 54 using std::string;
 55 using std::cout;
 56 using std::endl;
 57 using std::setw;
 58 
 59 class BookSale {
 60 public:
 61     BookSale(const Book &b, float price, int amount);
 62     int get_amount() const;
 63     
 64     friend ostream& operator<<(ostream &out, const BookSale &item);
 65 
 66 private:
 67     Book rb;         
 68     float sales_price;      // 售价
 69     int sales_amount;       // 销售数量
 70     float revenue;          // 营收
 71 };
 72 
 73 // 成员函数实现
 74 BookSale::BookSale(const Book &b, float price, int amount): rb{b}, sales_price(price), sales_amount{amount} {  
 75     revenue = sales_amount * sales_price;
 76 }
 77 
 78 int BookSale::get_amount() const {
 79     return sales_amount;
 80 }
 81 
 82 // 友元函数实现
 83 ostream& operator<<(ostream &out, const BookSale &item) {
 84     out << left;
 85     out << item.rb << endl
 86         << setw(15) << "售价:" << item.sales_price << endl
 87         << setw(15) << "销售数量:" << item.sales_amount << endl
 88         << setw(15) << "营收:" << item.revenue;
 89 
 90     return out;
 91 }
 92 #include "booksale.hpp"
 93 #include <iostream>
 94 #include <string>
 95 #include <vector>
 96 #include <algorithm>
 97 
 98 // 按图书销售数额比较
 99 bool compare_by_amount(const BookSale &x1, const BookSale &x2) {
100     return x1.get_amount() > x2.get_amount();
101 }
102 
103 void test() {
104     using namespace std;
105 
106      vector<BookSale> sales_lst;         // 存放图书销售记录
107 
108      int books_number;
109     cout << "录入图书数量: ";
110     cin >> books_number;
111 
112     cout << "录入图书销售记录" << endl;
113     for(int i = 0; i < books_number; ++i) {
114         string name, author, translator, isbn;
115         float price;
116         cout << string(20, '-') << "" << i+1 << "本图书信息录入" << string(20, '-') << endl;
117         cout << "录入书名: "; cin >> name;
118         cout << "录入作者: "; cin >> author;
119         cout << "录入译者: "; cin >> translator;
120         cout << "录入isbn: "; cin >> isbn;
121         cout << "录入定价: "; cin >> price;
122 
123         Book book(name, author, translator, isbn, price);
124 
125         float sales_price;
126         int sales_amount;
127 
128         cout << "录入售价: "; cin >> sales_price;
129         cout << "录入销售数量: "; cin >> sales_amount;
130 
131         BookSale record(book, sales_price, sales_amount);
132         sales_lst.push_back(record);
133     }
134 
135     // 按销售册数排序
136     sort(sales_lst.begin(), sales_lst.end(), compare_by_amount);
137 
138     // 按销售册数降序输出图书销售信息
139     cout << string(20, '=') <<  "图书销售统计" << string(20, '=') << endl;
140     for(auto &t: sales_lst) {
141         cout << t << endl;
142         cout << string(40, '-') << endl;
143     }
144 }
145 
146 int main() {
147     test();
148 }
View Code

 

(2)运行结果:

 

 

 

 

实验任务3:

(1)代码部分:

 1 #pragma once
 2 #include<iostream>
 3 using namespace std;
 4 class MachinePets {
 5 private:
 6     string nickname;
 7 public:
 8     MachinePets(const string &s);
 9     virtual string talk() const = 0;
10     string get_nickname() const;
11 };
12 MachinePets::MachinePets(const string& s) :nickname{ s }{}
13 string MachinePets::get_nickname()const {
14     return nickname;
15 }
16 class PetCats :public MachinePets {
17 public:
18     PetCats(const string& s);
19     string talk()const override;
20 };
21 PetCats::PetCats(const string& s) :MachinePets{ s } {
22 }
23 string PetCats::talk()const {
24     return "miao wu~";
25 }
26 class PetDogs :public MachinePets {
27 public:
28     PetDogs(const string& s);
29     string talk()const override;
30 };
31 PetDogs::PetDogs(const string &s):MachinePets{s}{}
32 string PetDogs::talk()const {
33     return "wang wang ~";
34 }
35 #include <iostream>
36 #include <vector>
37 #include "pets.hpp"
38 
39 void test() {
40     using namespace std;
41 
42     vector<MachinePets *> pets;
43 
44     pets.push_back(new PetCats("miku"));
45     pets.push_back(new PetDogs("da huang"));
46 
47     for(auto &ptr: pets)
48         cout <<ptr->get_nickname() << " says " << ptr->talk() << endl;
49 }
50 
51 int main() {
52     test();
53 }
View Code

 

(2)运行结果:

 

 

 

实验任务4:

(1)代码部分:

 1 film.hpp
 2 #pragma once
 3  #include<iostream>
 4  #include<iomanip>
 5  using namespace std;
 6 
 7  using std::left;
 8 
 9  class film {
10  private:
11          string name, director, area, time;
12  public:
13          film(const string & name = "", const string & director = "", const string & area = "", const string & time = "");
14          friend ostream & operator<<(ostream & out, const film & f);
15          friend istream & operator>>(istream & in, film & f);
16          string get_year()const;
17     
18 };
19  film::film(const string & name, const string & director, const string & area, const string & time) {
20          this->name = name;
21          this->director = director;
22          this->area = area;
23          this->time = time;
24     
25 }
26  string film::get_year()const {
27          return time;
28     
29 }
30  ostream & operator<<(ostream & out, const film & f) {
31          out << left;
32          out << setw(10)<<f.name << setw(15) << f.director << setw(10) << f.area << setw(10) << f.time << endl;
33          return out;
34     
35 }
36  istream & operator>>(istream & in, film & f) {
37         std::cout << "录入片名:";in >> f.name;
38         std::cout << "录入导演:";in >> f.director;
39         std::cout << "录入制片国家/地区:";in >> f.area;
40         std::cout << "录入上映年份:";in >> f.time;
41          return in;
42     
43 }
44  bool compare_by_year(const film & f1, const film & f2) {
45          return f1.get_year() < f2.get_year();
46     
47 }
48 task4.cpp
49 #include "film.hpp"
50 #include <iostream>
51 #include <string>
52 #include <vector>
53 #include <algorithm>
54 
55 void test() {
56     using namespace std;
57 
58     int n;
59     cout << "输入电影数目: ";
60     cin >> n;
61 
62     cout << "录入" << n << "部影片信息" << endl;
63     vector<film> film_lst;
64     for (int i = 0; i < n; ++i) {
65         film f;
66         cout << string(20, '-') << "" << i + 1 << "部影片录入" << string(20, '-') << endl;
67         cin >> f;
68         film_lst.push_back(f);
69     }
70 
71     // 按发行年份升序排序
72     sort(film_lst.begin(), film_lst.end(), compare_by_year);
73 
74     cout << string(20, '=') + "电影信息(按发行年份)" + string(20, '=') << endl;
75     for (auto& f : film_lst)
76         cout << f << endl;
77 }
78 
79 int main() {
80     test();
81 }
View Code

 

(2)运行结果:

 

 

 

 

 

实验任务5:

(1)代码部分:

 1 Complex.hpp
 2 #pragma once
 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     T get_real()const {
11         return real;
12     }
13     T get_imag()const {
14         return imag;
15     }
16     Complex operator+=(const Complex c) {
17         real += c.real;
18         imag += c.imag;
19         return *this;
20     }
21     friend Complex operator+(const Complex& c1, const Complex& c2) {
22         return Complex<T>(c1.real + c2.real, c1.imag + c2.imag);
23     }
24 
25     friend bool operator==(const Complex& c1, const Complex& c2) {
26         return c1.real == c2.real && c1.imag == c2.imag;
27     }
28 
29     friend istream& operator>>(istream& in,  Complex& c) {
30         in >> c.real >> c.imag;
31         return in;
32     }
33 
34     friend ostream& operator<<(ostream& out,const Complex& c) {
35         if (c.imag > 0)
36             out << c.real << '+' << c.imag << 'i';
37         else
38             out << c.real << '-' << -c.imag << 'i';
39         return out;
40     }
41 
42 
43 private:
44     T real;
45     T imag;
46 };
47 task5
48 #include "Complex.hpp"
49 #include <iostream>
50 
51 using std::cin;
52 using std::cout;
53 using std::endl;
54 using std::boolalpha;
55 
56 void test1() {
57     Complex<int> c1(2, -5), c2(c1);
58 
59     cout << "c1 = " << c1 << endl;
60     cout << "c2 = " << c2 << endl;
61     cout << "c1 + c2 = " << c1 + c2 << endl;
62 
63     c1 += c2;
64     cout << "c1 = " << c1 << endl;
65     cout << boolalpha << (c1 == c2) << endl;
66 }
67 
68 void test2() {
69     Complex<double> c1, c2;
70     cout << "Enter c1 and c2: ";
71     cin >> c1 >> c2;
72     cout << "c1 = " << c1 << endl;
73     cout << "c2 = " << c2 << endl;
74 
75     cout << "c1.real = " << c1.get_real() << endl;
76     cout << "c1.imag = " << c1.get_imag() << endl;
77 }
78 
79 int main() {
80     cout << "自定义类模板Complex测试1: " << endl;
81     test1();
82 
83     cout << endl;
84 
85     cout << "自定义类模板Complex测试2: " << endl;
86     test2();
87 }
View Code

 

(2)运行结果:

 

 

实验任务6:

(1)代码部分:

  1 #pragma once
  2 #include"date.h"
  3 #include"accumulator.h"
  4 #include<string>
  5 using namespace std;
  6 class Account {
  7 private:
  8         string id;
  9         double balance;
 10         static double total;
 11 protected:
 12         Account(const Date & date, const string & id);
 13         void record(const Date & date, double amount, const string & desc);
 14         void error(const string & msg) const;
 15 public:const string & getId() { return id; }
 16                double getBalance()const { return balance; }
 17                static double getTotal() { return total; }
 18                virtual void deposit(const Date & date, double amount, const string & desc) = 0;
 19                virtual void withdraw(const Date & date, double amount, const 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 };
 57 #pragma once
 58 #include "date.h"
 59 class Accumulator {
 60 private:
 61         Date lastDate;
 62         double value;
 63         double sum;
 64 public:
 65         Accumulator(const Date & date, double value) :lastDate(date), value(value), sum{ 0 } {}
 66         double getSum(const Date & date) const {
 67                 return sum + value * (date - lastDate);
 68     }
 69         void change(const Date & date, double value) {
 70                 sum = getSum(date);
 71                 lastDate = date;
 72                 this->value = value;
 73     }
 74         void reset(const Date & date, double value) {
 75                 lastDate = date;
 76                 this->value;
 77                 sum = 0;
 78     }
 79 };
 80 #pragma once
 81 class Date {
 82 private:
 83     int year;
 84     int month;
 85     int day;
 86     int totalDays;
 87 public:
 88     Date(int year, int month, int day);
 89     int getYear()const { return year; }
 90     int getMonth()const { return month; }
 91     int getDay()const { return day; }
 92     int getMaxDay()const;
 93     bool isLeapYear()const {
 94         return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
 95     }
 96     void show()const;
 97     int operator - (const Date & date)const {
 98         return totalDays - date.totalDays;
 99     }
100 };
101 #include "account.h"
102 #include <cmath>
103 #include<iostream>
104 using namespace std;
105 double Account::total = 0;
106 Account::Account(const Date & date, const string & id) :id(id), balance(0) {
107         date.show();
108         cout << "\t#" << id << "created" << endl;
109 }
110 void Account::record(const Date & date, double amount, const string & desc) {
111         amount = floor(amount * 100 + 0.5) / 100;
112         balance += amount;
113         total += amount;
114         date.show();
115         cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl;
116 }
117 void Account::show()const { cout << id << "\tBalance:" << balance; }
118 void Account::error(const string & msg)const {
119         cout << "Error(#" << id << "):" << msg << endl;
120 }
121 SavingsAccount::SavingsAccount(const Date & date, const string & id, double rate) :Account(date, id), rate(rate), acc(date, 0) {}
122 void SavingsAccount::deposit(const Date & date, double amount, const string & desc) {
123         record(date, amount, desc);
124         acc.change(date, getBalance());
125 }
126 void SavingsAccount::withdraw(const Date & date, double amount, const string & desc) {
127         if (amount > getBalance()) {
128                 error("not enough money");
129     }
130         else {
131                 record(date, -amount, desc);
132                 acc.change(date, getBalance());
133     }
134 }
135 void SavingsAccount::settle(const Date & date) {
136         if (date.getMonth() == 1) {
137                 double interest = acc.getSum(date) * rate / (date - Date(date.getYear() - 1, 1, 1));
138                 if (interest != 0) record(date, interest, "interest");
139                 acc.reset(date, getBalance());
140     }
141 }
142 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) {}
143 void CreditAccount::deposit(const Date & date, double amount, const string & desc) {
144         record(date, amount, desc);
145         acc.change(date, getDebt());
146 }
147 void CreditAccount::withdraw(const Date & date, double amount, const string & desc) {
148         if (amount - getBalance() > credit) {
149                 error("not enouogh credit");
150     }
151         else {
152                 record(date, -amount, desc);
153                 acc.change(date, getDebt());
154     }
155 }
156 void CreditAccount::settle(const Date & date) {
157         double interest = acc.getSum(date) * rate;
158         if (interest != 0) record(date, interest, "interest");
159         if (date.getMonth() == 1)record(date, -fee, "annual fee");
160         acc.reset(date, getDebt());
161 }
162 void CreditAccount::show()const {
163         Account::show();
164         cout << "\tAvailable credit:" << getAvailableCredit();
165 }
166 #include"account.h"
167 #include<iostream>
168 using namespace std;
169 int main() {
170         Date date(2008, 11, 1);
171         SavingsAccount sa1(date, "S3755217", 0.015);
172         SavingsAccount sa2(date, "02342342", 0.015);
173         CreditAccount ca(date, "C5392394", 10000, 0.0005, 50);
174         Account * accounts[] = { &sa1,&sa2,&ca };
175         const int n = sizeof(accounts) / sizeof(Account*);
176         cout << "(d)deposit (w)withdraw (s)show (c)change day (n)next month (e)exit" << endl;
177         char cmd;
178         do {
179                 date.show();
180                 cout << "\tTotal:" << Account::getTotal() << "\tcommand>";
181                 int index, day;
182                 double amount;
183                 string desc;
184                 cin >> cmd;
185                 switch (cmd) {
186                 case 'd':
187                         cin >> index >> amount;
188                         getline(cin, desc);
189                         accounts[index]->deposit(date, amount, desc);
190                         break;
191                 case 'w':
192                         cin >> index >> amount;
193                         getline(cin, desc);
194                         accounts[index]->withdraw(date, amount, desc);
195                         break;
196                 case 's':
197                         for (int i = 0; i < n; i++) {
198                                 cout << "[" << i << "]";
199                                 accounts[i]->show();
200                                 cout << endl;
201             }
202                         break;
203                 case 'c':
204                         cin >> day;
205                         if (day < date.getDay()) {
206                                 cout << "You cannot specify a previous day";
207             }
208                         else if (day > date.getMaxDay())
209                                 cout << "Invalid day";
210                         else date = Date(date.getYear(), date.getMonth(), day);
211                         break;
212                 case 'n':
213                         if (date.getMonth() == 12)
214                                 date = Date(date.getYear() + 1, 1, 1);
215                         else date = Date(date.getYear(), date.getMonth() + 1, 1);
216                         for (int i = 0; i < n; i++) {
217                                 accounts[i]->settle(date);
218             }
219                         break;
220         }
221     } while (cmd != 'e');
222         return 0;
223 }
224 #include"date.h"
225 #include<iostream>
226 #include<cstdlib>
227 using namespace std;
228 namespace {
229     const int DAYS_BEFIRE_MONTH[] = { 0,31,59,90,120,151,181,212,243,273,304,334,365 };
230 }
231 Date::Date(int year, int month, int day) :year(year), month(month), day(day) {
232     if (day <= 0 || day > getMaxDay()) {
233         cout << "Invalid date:";
234         show();
235         cout << endl;
236         exit(1);
237     }
238     int years = year - 1;
239     totalDays = years * 365 + year / 4 - years / 100 + years / 400 + DAYS_BEFIRE_MONTH[month - 1] + day;
240     if (isLeapYear() && month > 2)totalDays++;
241 }
242 int Date::getMaxDay()const {
243         if (isLeapYear() && month == 2)
244                 return 29;
245         else return DAYS_BEFIRE_MONTH[month] - DAYS_BEFIRE_MONTH[month - 1];
246 }
247 void Date::show()const {
248     cout << getYear() << "-" << getMonth() << "-" << getDay();
249 }
View Code

 

posted @ 2024-12-07 14:44  刘晔yyy  阅读(6)  评论(0编辑  收藏  举报