guguabiu

导航

实验5

实验任务1:

publisher.hpp:

 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 class Publisher{
11 public:
12     Publisher(const string &s = "");
13     
14 public:
15     virtual void publish() const = 0;
16     virtual void use() const = 0;
17     
18 protected:
19     string name;
20 };
21 
22 Publisher::Publisher(const string &s):name{s}{
23 }
24 
25 class Book:public Publisher{
26 public:
27     Book(const string &s = "",const string &a = "");
28     
29 public:
30     void publish() const override;
31     void use() const override;
32     
33 private:
34     string author;
35 };
36 
37 Book::Book(const string &s,const string &a):Publisher{s},author{a}{
38 }
39 
40 void Book::publish() const {
41     cout << "Publishing book: 《" << name << "》by" << author << endl;
42 }
43 
44 void Book::use() const {
45     cout << "Reading book: " << name << "by" << author << endl;
46 }
47 
48 class Film:public Publisher {
49 public:
50     Film(const string &s = " ",const string &d = " ");
51 
52 public:
53     void publish() const override;
54     void use() const override;
55     
56 private:
57     string director;
58 };
59 
60 Film::Film(const string &s,const string &d):Publisher{s},director{d}{
61 }
62 
63 void Film::publish() const {
64     cout << "Publishing film:<" << name << "> directored by " << director << endl;
65 }
66 
67 void Film::use() const {
68     cout << "watching film: " << name << "directored by " << director << endl;
69 }
70 
71 class Music:public Publisher {
72 public:
73     Music(const string &s = "",const string &a = "");
74     
75 public:
76     void publish() const override;
77     void use() const override;
78     
79 private:
80     string artist;
81 };
82 
83 Music::Music(const string &s,const string &a):Publisher{s},artist{a}{
84 }
85 
86 void Music::publish() const {
87     cout << "Publishing music <" << name << "> by " << artist << endl;
88 }
89 
90 void Music::use() const {
91     cout << "Listening to music: " << name << " by " << artist << endl;
92 }
View Code

task1.cpp:

 1 #include"publisher.hpp"
 2 #include<vector>
 3 #include<typeinfo>
 4 
 5 using std::vector;
 6 
 7 void test(){
 8     vector<Publisher *> v;
 9     
10     v.push_back(new Book("Harry Potter","J.K.Rowling"));
11     v.push_back(new Film("The Godfather","Franci Ford Coppola"));
12     v.push_back(new Music("Blowing in the wind","Bob Dylan"));
13     
14     for(auto &ptr: v){
15         cout << "pointer type: " << typeid(ptr).name() << endl;
16         cout << "RTTI type: " << typeid(*ptr).name() << endl;
17         ptr->publish();
18         ptr->use();
19         cout << endl;
20     }
21 }
22 
23 int main(){
24     test();
25 }
View Code

实验任务2:

book.hpp:

 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     friend ostream& operator<<(ostream &out,const Book &book);
17 
18 private:
19     string name;
20     string author;
21     string translator;
22     string isbn;
23     float price;
24 };
25 
26 Book::Book(const string &name,const string &author,const string &translator,const string &isbn,float price){
27     this->name = name;
28     this->author = author;
29     this->translator = translator;
30     this->isbn = isbn;
31     this->price = price;
32 }
33 
34 ostream& operator<<(ostream &out,const Book &book){
35     out << left;
36     out << setw(15) << "书名: " << book.name << endl
37         << setw(15) << "作者: " << book.author << endl
38         << setw(15) << "译者: " << book.translator << endl
39         << setw(15) << "定价: " << book.price;
40     
41     return out;
42 }
View Code

booksale.hpp:

 1 #pragma once
 2 
 3 #include "book.hpp"
 4 #include <iostream>
 5 #include <string>
 6 #include <iomanip>
 7 
 8 using std::string;
 9 using std::cout;
10 using std::endl;
11 using std::setw;
12 
13 class BookSale {
14 public:
15     BookSale(const Book &b,float price,int amount);
16     int get_amount() const;
17     friend ostream& operator<<(ostream &out,const BookSale &item);
18     
19 private:
20     Book rb;
21     float sales_price;
22     int sales_amount;
23     float revenue;
24 };
25 
26 BookSale::BookSale(const Book &b,float price,int amount):rb{b},sales_price{price},sales_amount{amount}{
27     revenue = sales_amount * sales_price;
28 }
29 
30 int BookSale::get_amount() const {
31     return sales_amount;
32 }
33 
34 ostream& operator<<(ostream &out,const BookSale &item){
35     out << left;
36     out << item.rb << endl
37         << setw(15) << "售价: " << item.sales_price << endl
38         << setw(15) << "销售数量: " << item.sales_amount << endl
39         << setw(15) << "营收: " << item.revenue;
40         
41     return out;
42 }
View Code

task2.cpp:

 1 #include "booksale.hpp"
 2 #include <iostream>
 3 #include <string>
 4 #include <vector>
 5 #include <algorithm>
 6 
 7 bool compare_by_amount(const BookSale &x1,const BookSale &x2){
 8     return x1.get_amount() > x2.get_amount();
 9 }
10 
11 void test(){
12     using namespace std;
13     
14     vector<BookSale> sales_lst;
15     
16     int books_number;
17     cout << "录入图书数量: ";
18     cin >> books_number;
19     cout << "录入图书销售记录" << endl;
20     for(int i = 0;i < books_number;++i){
21         string name,author,translator,isbn;
22         float price;
23         cout << string(20,'-') << "" << i+1 << "本图书信息录入" << string(20,'-') << endl;
24         cout << "录入书名: ";cin >> name;
25         cout << "录入作者: ";cin >> author;
26         cout << "录入译者: ";cin >> translator;
27         cout << "录入isbn: ";cin >> isbn;
28         cout << "录入定价: ";cin >> price;
29         
30         Book book(name,author,translator,isbn,price);
31         
32         float sales_price;
33         int sales_amount;
34         
35         cout << "录入售价: ";cin >> sales_price;
36         cout << "录入销售数量: ";cin >> sales_amount;
37         
38         BookSale record(book,sales_price,sales_amount);
39         sales_lst.push_back(record);
40     }
41     
42     sort(sales_lst.begin(),sales_lst.end(),compare_by_amount);
43     
44     cout << string(20,'=') << "图书销售统计" << string(20,'=') << endl;
45     for(auto &t:sales_lst){
46         cout << t << endl;
47         cout << string(40,'-') << endl;
48     }
49 }
50 
51 int main(){
52     test();
53 }
View Code

 

实验任务3:

pets.hpp:

 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 class MachinePets{  
11 public:  
12     MachinePets(const string &s = " ");  
13     string get_nickname() const;  
14 
15 public:  
16     virtual string talk() = 0;  
17 
18 private:  
19     string nickname;  
20 };  
21 
22 MachinePets::MachinePets(const string &s):nickname{s}{  
23 }  
24  
25 string MachinePets::get_nickname() const{
26     return nickname;  
27 }  
28 
29 class PetCats:public MachinePets{  
30 public:  
31     PetCats(const string &s = " ");  
32 
33 public:  
34     string talk() override;  
35 };  
36 
37 PetCats::PetCats(const string &s):MachinePets(s){  
38 }  
39  
40 string PetCats::talk(){  
41     return  " miao wu~";  
42 }  
43 
44 class PetDogs:public MachinePets{  
45 public:  
46     PetDogs(const string &s = " ");  
47 
48 public:  
49     string talk() override;  
50 };  
51 
52 PetDogs::PetDogs(const string &s):MachinePets(s){  
53 }  
54 
55 string PetDogs::talk(){  
56     return " wang wang~"; 
57 }

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 #pragma once  
 2 
 3 #include<iostream>  
 4 #include<string> 
 5 #include<iomanip> 
 6 
 7 using std::string;  
 8 using std::istream;  
 9 using std::ostream;  
10 using std::cout;
11 using std::setw;
12 using std::left;
13 using std::endl;
14 
15 class Film {  
16 public:   
17     Film(const string &title = " ", const string &director = " ", const string &country = " ", int year = 0);
18     int get_year() const {return year;}
19        
20     friend istream& operator >> (istream &in, Film &film);
21     friend ostream& operator << (ostream &out, const Film &film); 
22  
23 private:  
24     string title;       
25     string director;   
26     string country;      
27     int year;            
28 };
29 
30 Film::Film(const string &title, const string &director, const string &country, int year){
31     this->title = title;
32     this->director = director;
33     this->country = country;
34     this->year = year;
35 }
36 
37 istream& operator >> (istream &in, Film &film){  
38     cout << "录入片名: ";  
39     in >> film.title;   
40     cout << "录入导演: ";  
41     in >> film.director;  
42     cout << "录入制片国家/地区: ";  
43     in >> film.country;  
44     cout << "录入上映年份: ";  
45     in >> film.year;  
46     return in;  
47 } 
48     
49 ostream& operator << (ostream &out, const Film &film) { 
50     out << left;
51     out << film.title
52         << setw(15) << film.director << setw(15) << film.country << setw(15) << film.year;
53           
54     return out;  
55 }    
56  
57 bool compare_by_year(const Film &a, const Film &b) {  
58     return a.get_year() < b.get_year();  
59 }
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     sort(film_lst.begin(), film_lst.end(), compare_by_year);
24 
25     cout << string(20, '=') + "电影信息(按发行年份)" +  string(20, '=')<< endl;
26     for(auto &f: film_lst)
27         cout << f << endl;
28 }
29 
30 int main() {
31     test();
32 }
View Code

 

实验任务5:

Complex.hpp:

 1 #pragma once  
 2 
 3 #include <iostream> 
 4 #include<vector>  
 5 
 6 using namespace std;  
 7 
 8 template <typename T>  
 9 class Complex {  
10 public:     
11     Complex(T real = 0, T imag = 0) : real(real), imag(imag) {}   
12     T get_real() const { return real; }  
13     T get_imag() const { return imag; } 
14        
15     Complex &operator+=(const Complex &other) {  
16         real += other.real;  
17         imag += other.imag;  
18         return *this;  
19     }  
20  
21     Complex operator+(const Complex &other) const {  
22         return Complex(real + other.real, imag + other.imag);  
23     }  
24  
25     bool operator==(const Complex &other) const {  
26         return (real == other.real) && (imag == other.imag);  
27     }  
28 
29     friend istream &operator>>(istream &in, Complex &c) {   
30         in >> c.real;  
31         in >> c.imag;  
32         return in;  
33     }   
34    
35     friend ostream &operator<<(ostream &out, const Complex &c) {    
36         if(c.imag > 0) 
37             out << c.real << " + " << c.imag << "i";
38         else
39             out << c.real << " " << c.imag << "i"; 
40         return out;  
41     }
42     
43 private:  
44     T real; 
45     T imag;   
46 };  

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     cout << "c1 = " << c1 << endl;
12     cout << "c2 = " << c2 << endl;
13     cout << "c1 + c2 = " << c1 + c2 << endl;
14     c1 += c2;
15     cout << "c1 = " << c1 << endl;
16     cout << boolalpha << (c1 == c2) << endl;
17 }
18 
19 void test2() {
20     Complex<double> c1, c2;
21     cout << "Enter c1 and c2: ";
22     cin >> c1 >> c2;
23     cout << "c1 = " << c1 << endl;
24     cout << "c2 = " << c2 << endl;
25     cout << "c1.real = " << c1.get_real() << endl;
26     cout << "c1.imag = " << c1.get_imag() << endl;
27 }
28 
29 int main() {
30     cout << "自定义类模板Complex测试1: " << endl;
31     test1();
32     cout << endl;
33     cout << "自定义类模板Complex测试2: " << endl;
34     test2();
35 }
View Code

 

实验任务6:

 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     int operator-(const Date& date) const {
20         return totalDays - date.totalDays;
21     }
22 };
23 #endif //__DATE_H__
View Code

 

date.cpp:

 1 #include "date.h"
 2 #include <iostream>
 3 #include <cstdlib>
 4 using namespace std;
 5 
 6 namespace {
 7     const int DAYS_BEFORE_MONTH[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
 8 }
 9 
10 Date::Date(int year, int month, int day) : year(year), month(month), day(day) {
11     if (day <= 0 || day > getMaxDay()) {
12         cout << "Invalid date: ";
13         show();
14         cout << endl;
15         exit(1);
16     }
17     int years = year - 1;
18     totalDays = years * 365 + years / 4 - years / 100 + years / 400 + DAYS_BEFORE_MONTH[month - 1] + day;
19     if (isLeapYear() && month > 2) totalDays++;
20 }
21 
22 int Date::getMaxDay() const {
23     if (isLeapYear() && month == 2)
24         return 29;
25     else return DAYS_BEFORE_MONTH[month] - DAYS_BEFORE_MONTH[month - 1];
26 }
27 
28 void Date::show() const {
29     cout << getYear() << "-" << getMonth() << "-" << getDay();
30 }
View Code

 

accumulator.h:

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

 

account.h:

 1 #ifndef __ACCOUNT_H__
 2 #define __ACCOUNT_H__
 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 #endif //__ACCOUNT_H__
View Code

 

account.cpp:

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

 

8_8.cpp:

 1 #include "account.h"
 2 #include<iostream>
 3 
 4 using namespace std;
 5 
 6 int main() {
 7     Date date(2008, 11, 1);
 8     SavingsAccount sa1(date, "S3755217", 0.015);
 9     SavingsAccount sa2(date, "02342342", 0.015);
10     CreditAccount ca(date, "C5392394", 10000, 0.0005, 50);
11     Account* accounts[] = { &sa1, &sa2, &ca };
12     const int n = sizeof(accounts) / sizeof(Account*);
13     cout << "(d)deposit (w)withdraw (s)show (c)change day (n)next month (e)exit" << endl;
14     char cmd;
15     do {
16         date.show();
17         cout << "\tTotal:" << Account::getTotal() << "\tcommand>";
18         int index, day;
19         double amount;
20         string desc;
21         cin >> cmd;
22         switch (cmd) {
23         case 'd':
24             cin >> index >> amount;
25             getline(cin, desc);
26             accounts[index]->deposit(date, amount, desc);
27             break;
28         case 'w':
29             cin >> index >> amount;
30             getline(cin, desc);
31             accounts[index]->withdraw(date, amount, desc);
32             break;
33         case 's':
34             for (int i = 0; i < n; i++) {
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             }
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 }
View Code

 

 

 在基类Account中将账户的公共操作皆声明为虚函数,可以通过基类的指针来进行各种操作,各种类型的账户对象都可以通过一个基类指针的数组来访问,提供了极大的便利,可以通过统一的方式来操作各个账户。

posted on 2024-12-09 14:45  絮尘。  阅读(6)  评论(0编辑  收藏  举报