实验5 继承和多态

实验任务3:

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

pets.cpp:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class MachinePets {
 7 public:
 8     MachinePets(const string& s):nickname(s){}
 9     string get_nickname() const{return nickname;}
10     virtual string talk() = 0;
11 protected:
12     string nickname;
13 };
14 
15 class PetCats : public MachinePets {
16 public:
17     PetCats(const string& s):MachinePets(s){}
18     string talk() override{return "miao wu~";}
19 };
20 
21 class PetDogs : public MachinePets {
22 public:
23     PetDogs(const string& s):MachinePets(s){}
24     string talk() override{return "wang wang~";}
25 };

运行结果:

 

 实验任务4:

 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

film.hpp:

 1 #pragma once
 2 #include <iostream>
 3 #include <string>
 4 #include <iomanip>
 5 
 6 using namespace std;
 7 
 8 class Film {
 9 public:
10     Film() = default;
11     Film(string t, string d, int y, string p) : title(t), director(d), year(y), place(p) {}
12 
13     int getYear() const { return year; }
14 
15     friend istream& operator>>(istream& is, Film& f)
16     {
17         cout << "录入片名: "; is >> f.title;
18         cout << "录入导演: "; is >> f.director;
19         cout << "录入制片国家/地区: "; is >> f.place;
20         cout << "录入上映年份: "; is >> f.year;
21         return is;
22     }
23 
24     friend ostream& operator<<(ostream& os, const Film& f)
25     {
26         os << left << setw(20) << f.title << setw(20) << f.director << setw(20) << f.place << setw(20) << f.year << endl;
27         return os;
28     }
29 
30 private:
31     string title;
32     string director;
33     int year;
34     string place;
35 };
36 
37 bool compare_by_year(const Film& f1, const Film& f2)
38 {
39     if (f1.getYear() < f2.getYear())
40         return true;
41     return false;
42 }

运行结果:

 

实验任务5:

 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

Complex.hpp:

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

运行结果:

 

实验任务6:

 8_8.cpp:

#include "account.h"
#include <iostream>
using namespace std;
int main() {
    Date date(2008, 11, 1);        //起始日期
    //建立几个账户
    SavingsAccount sa1(date, "S3755217", 0.015);
    SavingsAccount sa2(date, "02342342", 0.015);
    CreditAccount ca(date, "C5392394", 10000, 0.0005, 50);
    Account *accounts[] = {&sa1, &sa2, &ca};
    const int n=sizeof(accounts)/sizeof(Account*);        //账户总数
    cout << "(d)deposit(w)withdraw(s)show(c)change day(n)next month(e)exit" << endl;
    char cmd;
    do {
        //显示日期和总金额
        date.show();
        cout << "\tTotal: " << Account::getTotal() << "\tcommand>";
        int index, day;
        double amount;
        string desc;
        cin >> cmd;
        switch (cmd) {
        case 'd':    //存入现金
            cin >> index >> amount;
            getline(cin, desc);
            accounts[index]->deposit(date, amount, desc);
            break;
        case 'w':    //取出现金
            cin >> index >> amount;
            getline(cin, desc);
            accounts[index]->withdraw(date, amount, desc);
            break;
        case's':    //查询各账户信息
            for (int i = 0; i < n; i++) {
                cout << "[" << i << "]";
                accounts[i]->show();
                cout << endl;
            }
            break;
        case 'c':    //改变日期
            cin >> day;
            if (day < date.getDay())
                cout << "You cannot specify a previous date";
            else if (day > date.getMaxDay())
                cout << "Invalid day";
            else
                date = Date(date.getYear(), date.getMonth(), day);
            break;
        case 'n':    //进入下一月
            if (date.getMonth() == 12)
                date = Date(date.getYear() + 1, 1, 1);
            else
                date = Date(date.getYear(), date.getMonth() + 1, 1);
            for (int i = 0; i < n; i++)
                accounts[i]->settle(date);
            break;
        }
    }while (cmd != 'e');
    return 0;
}
View Code

account.cpp:

#include"account.h"
#include<cmath>
#include<iostream>
using namespace std;
double Account::total = 0;

Account::Account(const Date& date, const string& id) :id{ id }, balance{ 0 } {
    date.show(); cout << "\t#" << id << "created" << endl;
}


void Account::record(const Date& date, double amount, const string& desc) {
    amount = floor(amount * 100 + 0.5) / 100;
    balance += amount;
    total += amount;
    date.show();
    cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl;
}

void Account::show()const { cout << id << "\tBalance:" << balance; }
void Account::error(const string& msg)const {
    cout << "Error(#" << id << "):" << msg << endl;
}

SavingsAccount::SavingsAccount(const Date& date, const string& id, double rate) :Account(date, id), rate(rate), acc(date, 0) {}

void SavingsAccount::deposit(const Date& date, double amount, const string& desc) {
    record(date, amount, desc);
    acc.change(date, getBalance());
}

void SavingsAccount::withdraw(const Date& date, double amount, const string& desc) {
    if (amount > getBalance()) {
        error("not enough money");
    }
    else {
        record(date, -amount, desc);
        acc.change(date, getBalance());
    }
}

void SavingsAccount::settle(const Date& date) {
    if (date.getMonth() == 1) {     //每年的1月计算一次利息
        double interest = acc.getSum(date) * rate / (date - Date(date.getYear() - 1, 1, 1));
        if (interest != 0)
            record(date, interest, "interest");
        acc.reset(date, getBalance());
    }
}

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) {}

void CreditAccount::deposit(const Date& date, double amount, const string& desc) {
    record(date, amount, desc);
    acc.change(date, getDebt());
}

void CreditAccount::withdraw(const Date& date, double amount, const string& desc) {
    if (amount - getBalance() > credit) {
        error("not enough credit");
    }
    else {
        record(date, -amount, desc);
        acc.change(date, getDebt());
    }
}

void CreditAccount::settle(const Date& date) {
    double interest = acc.getSum(date) * rate;
    if (interest != 0)record(date, interest, "interest");
    if (date.getMonth() == 1)
        record(date, -fee, "annual fee");
    acc.reset(date, getDebt());
}

void CreditAccount::show()const {
    Account::show();
    cout << "\tAvailable credit:" << getAvailableCredit();
}
View Code

account.h:

#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__
#include "date.h"
#include "accumulator.h"
#include <string>

class Account {                //账户类
private:
    std::string id;            //账户
    double balance;            //余额
    static double total;    //所有账户的总金额
protected:
    //供派生类调用的构造函数,id为账户
    Account(const Date& date, const std::string& id);
    //记录一笔账,date为日期,amount为金额,desc为说明
    void record(const Date& date, double amount, const std::string& desc);
    //报告错误信息
    void error(const std::string& msg) const;
public:
    const std::string& getId() const { return id; }
    double getBalance() const { return balance; }
    static double getTotal() { return total; }
    //存入现金,date为日期,amount为金额,desc为款项说明
    virtual void deposit(const Date& date, double amount, const std::string& desc) = 0;
    //取出现金,date为日期,amount为金额,desc为款项说明
    virtual void withdraw(const Date& date, double amount, const std::string& desc) = 0;
    //结算(计算利息、年费等),每月结算一次,date为结算日期
    virtual void settle(const Date& date) = 0;
    //显示账户信息
    virtual void show() const;
};
class SavingsAccount :public Account {
private:
    Accumulator acc;
    double rate;
public:
    SavingsAccount(const Date& date, const std::string& id, double rate);
    double getRate()const { return rate; }

    void deposit(const Date& date, double amount, const std::string& desc);
    void withdraw(const Date& date, double amount, const std::string& desc);
    void settle(const Date& date);
};
class CreditAccount :public Account {
private:
    Accumulator acc;
    double credit;
    double rate;
    double fee;
    double getDebt()const {
        double balance = getBalance();
        return (balance < 0 ? balance : 0);
    }
public:
    CreditAccount(const Date& date, const std::string& id, double credit, double rate, double fee);
    double getCredit()const { return credit; }
    double getRate()const { return rate; }
    double getAvailableCredit()const {
        if (getBalance() < 0)
            return credit + getBalance();
        else
            return credit;
    }
    void deposit(const Date& date, double amount, const std::string& desc);
    void withdraw(const Date& date, double amount, const std::string& desc);
    void settle(const Date& date);
    void show()const;
};
#endif //__ACCOUNT_H__
View Code

accumulator.h:

#ifndef __ACCUMULATOR_H__
#define __ACCUMULATOR_H__
#include "date.h"
class Accumulator {        //将某个数值按日累加
private:
    Date lastDate;        //上次变更数值的日期
    double value;        //数值的当前值
    double sum;            //数值按日累加之和
public:
    //构造函数,date为开始累加的日期,value为初始值
    Accumulator(const Date& date, double value) : lastDate(date), value(value), sum(0) {}
    //获得到日期date的累加结果
    double getSum(const Date& date) const {
        return sum + value * (date - lastDate);
    }
    //在date将数值变更为value
    void change(const Date& date, double value) {
        sum = getSum(date);
        lastDate = date;
        this->value = value;
    }
    //初始化,将日期变为date,数值变为value,累加器清零
    void reset(const Date& date, double value) {
        lastDate = date;
        this->value = value;
        sum = 0;
    }
};
#endif //__ACCUMULATOR_H__
View Code

date.cpp:

#include"date.h"
#include<iostream>
#include<cstdlib>
using namespace std;
namespace {
    const int DAYS_BEFORE_MONTH[] = { 0,31,59,90,120,151,181,212,243,273,304,334,365 };
}
Date::Date(int year, int month, int day) :year{ year }, month{ month }, day{ day } {
    if (day <= 0 || day > getMaxDay()) {
        cout << "Invalid date:";
        show();
        cout << endl;
        exit(1);
    }
    int years = year - 1;
    totalDays = years * 365 + years / 4 - years / 100 + years / 400 + DAYS_BEFORE_MONTH[month - 1] + day;
    if (isLeapYear() && month > 2)totalDays++;
}
int Date::getMaxDay()const {
    if (isLeapYear() && month == 2)
        return 29;
    else 
        return DAYS_BEFORE_MONTH[month] - DAYS_BEFORE_MONTH[month - 1];
}

void Date::show()const {
    cout << getYear() << "-" << getMonth() << "-" << getDay();
}
View Code

date.h:

//date.h
#ifndef __DATE_H__
#define __DATE_H__
class Date {    //日期类
private:
    int year;        //
    int month;        //
    int day;        //
    int totalDays;    //该日期是从公元元年1月1日开始的第几天
public:
    Date(int year, int month, int day);        //用年、月、日构造日期
    int getYear() const { return year; }
    int getMonth() const { return month; }
    int getDay() const { return day; }
    int getMaxDay() const;        //获取当月有多少天
    bool isLeapYear() const {        //判断当年是否为闰年
        return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    }
    void show() const;        //输出当前日期
    int operator-(const Date& date) const {        //计算两个日期之间差多少天
        return totalDays - date.totalDays;
    }
};
#endif    //__DATE_H__
View Code

运行结果:

 

posted @ 2024-12-04 18:00  wuxin404  阅读(5)  评论(0编辑  收藏  举报