实验5 继承和多态

任务1:

task1.cpp

  1 publisher.hpp:
  2 #pragma once
  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 
101 task1.cpp:
102 #include "publisher.hpp"
103 #include <vector>
104 #include <typeinfo>
105 
106 using std::vector;
107 
108 void test() {
109     vector<Publisher*> v;
110 
111     v.push_back(new Book("Harry Potter", "J.K. Rowling"));
112     v.push_back(new Film("The Godfather", "Francis Ford Coppola"));
113     v.push_back(new Music("Blowing in the wind", "Bob Dylan"));
114 
115     for (auto& ptr : v) {
116         cout << "pointer type: " << typeid(ptr).name() << endl;  // 输出指针类型
117         cout << "RTTI type: " << typeid(*ptr).name() << endl;    // 输出指针指向的对象类型
118         ptr->publish();
119         ptr->use();
120         cout << endl;
121     }
122 }
123 
124 int main() {
125     test();
126 }
View Code

 

任务2:

task2.cpp

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

问题1:用友元函数重载输出流<<两参数为out和item;

问题2:自定义函数compare_by_amount,参数类型为booksale;

问题3:用了book类中的带参数构造函数;

任务3:

task3.cpp

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

 

任务4:

task4.cpp

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

 

 

任务5:

task5.cpp

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

 

任务6:

task6.cpp

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

 

posted @ 2024-12-08 17:45  Altairsss  阅读(1)  评论(0编辑  收藏  举报