实验5

#pragma once

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

// 发行/出版物类:Publisher (抽象类)
class Publisher {
public:
Publisher(const string &s = ""); // 构造函数

public:
virtual void publish() const = 0; // 纯虚函数,作为接口继承
virtual void use() const = 0; // 纯虚函数,作为接口继承

protected:
string name; // 发行/出版物名称
};

Publisher::Publisher(const string &s): name {s} {
}


// 图书类: Book
class Book: public Publisher {
public:
Book(const string &s = "", const string &a = ""); // 构造函数

public:
void publish() const override; // 接口
void use() const override; // 接口

private:
string author; // 作者
};

Book::Book(const string &s, const string &a): Publisher{s}, author{a} {
}

void Book::publish() const {
cout << "Publishing book: 《" << name << "》 by " << author << endl;
}

void Book::use() const {
cout << "Reading book: " << name << " by " << author << endl;
}


// 电影类: Film
class Film: public Publisher {
public:
Film(const string &s = "", const string &d = ""); // 构造函数

public:
void publish() const override; // 接口
void use() const override; // 接口

private:
string director; // 导演
};

Film::Film(const string &s, const string &d): Publisher{s}, director{d} {
}

void Film::publish() const {
cout << "Publishing film: <" << name << "> directed by " << director << endl;
}

void Film::use() const {
cout << "Watching film: " << name << " directed by " << director << endl;
}


// 音乐类:Music
class Music: public Publisher {
public:
Music(const string &s = "", const string &a = "");

public:
void publish() const override; // 接口
void use() const override; // 接口

private:
string artist; // 音乐艺术家名称
};

Music::Music(const string &s, const string &a): Publisher{s}, artist{a} {
}

void Music::publish() const {
cout << "Publishing music <" << name << "> by " << artist << endl;
}

void Music::use() const {
cout << "Listening to music: " << name << " by " << artist << endl;
}

#include "publisher.hpp"
#include <vector>
#include <typeinfo>

using std::vector;

void test() {
   vector<Publisher *> v;

   v.push_back(new Book("Harry Potter", "J.K. Rowling"));
   v.push_back(new Film("The Godfather", "Francis Ford Coppola"));
   v.push_back(new Music("Blowing in the wind", "Bob Dylan"));

   for(auto &ptr: v) {
        cout << "pointer type: " << typeid(ptr).name() << endl;  // 输出指针类型
        cout << "RTTI type: " << typeid(*ptr).name() << endl;    // 输出指针指向的对象类型
        ptr->publish();
        ptr->use();
        cout << endl;
   }
}

int main() {
    test();
}

 实验二

#pragma once
#include <bits/stdc++.h>
using namespace std;

class Book{
public:
    Book(const string &name,const string &author,const string translator,const string isbn,float price);
    friend ostream& operator<<(ostream& out,const Book &book);

private:
    string name;
    string author;
    string translator;
    string isbn;
    float price;
};

Book::Book(const string &name,const string &author,const string translator,const string isbn,float price)
{
    this->name=name;
    this->author=author;
    this->translator=translator;
    this->isbn=isbn;
    this->price=price;
}

ostream& operator<<(ostream &out,const Book &book)
{
    out<<left;
    out<<setw(15)<<"书名:"<<book.name<<endl
       <<setw(15)<<"作者:"<<book.author<<endl
       <<setw(15)<<"译者:"<<book.translator<<endl
       <<setw(15)<<"定价:"<<book.price<<endl;
    return out;
}
#pragma once
#include "book.hpp";
#include <bits/stdc++.h>
using namespace std;

class BookSale{
public:
    BookSale(const Book &b,float price,int amount);
    int get_amount() const;
    
    friend ostream& operator<<(ostream& out,const BookSale &item);
private:
     Book rb;
     float sales_price;
     int sales_amount;
     float revenue;
};

BookSale::BookSale(const Book &b,float price,int amount):
rb(b),sales_price(price),sales_amount(amount){
    revenue=sales_amount*sales_price;
}

int BookSale::get_amount() const
{
    return sales_amount;
}

ostream& operator<<(ostream &out,const BookSale &item)
{
    out<<left;
    out<<item.rb<<endl
       <<setw(15)<<"售价:"<<item.sales_price<<endl
       <<setw(15)<<"销售数量:"<<item.sales_amount<<endl
       <<setw(15)<<"营收:"<<item.revenue<<endl;
    return out;
}
#include "booksale.hpp"
#include <bits/stdc++.h>
using namespace std;

bool compare_by_amount(const BookSale &x1,const BookSale &x2)
{
    return x1.get_amount()>x2.get_amount();
}

void test()
{
    vector<BookSale> sales_lst;
    
    int books_number;
    cout<<"录入图书数量:";
    cin>>books_number;
    
    cout<<"录入图书销售记录:"<<endl;
    for (int i=0;i<books_number;++i)
    {
        string name,author,translator,isbn;
        float price;
        cout<<string(20,'-')<<""<<i+1<<"本图书信息录入"<<string(20,'-')<<endl;
        cout<<"录入书名:";cin>>name;
        cout<<"录入作者:";cin>>author;
        cout<<"录入译者:";cin>>translator;
        cout<<"录入isbn:";cin>>isbn;
        cout<<"录入定价:";cin>>price;
        Book book(name,author,translator,isbn,price);
        float sales_price;
        int sales_amount;
        
        cout<<"录入售价:";cin>>sales_price;
        cout<<"录入销售数量:";cin>>sales_amount;
        
        BookSale record(book,sales_price,sales_amount);
        sales_lst.push_back(record);
    }
    sort(sales_lst.begin(),sales_lst.end(),compare_by_amount);
    
    cout<<string(20,'=')<<"图书销售统计"<<string(20,'=')<<endl;
    for (auto &t:sales_lst){
        cout<<t<<endl;
        cout<<string(40,'-')<<endl;
    }
}

int main ()
{
    test();
}

实验三

#pragma once
#include <bits/stdc++.h>
using namespace std;

class MachinePets{
private:
    string nickname;
public:
    MachinePets(const string &s=""):nickname(s){};
    string get_nickname() const {return nickname;};
    virtual string talk() const=0;
};

class PetCats:public MachinePets{
public:
    PetCats(const string &s):MachinePets(s){};
    string talk()const override{return "miao wu\n";}
};

class PetDogs:public MachinePets{
public:
    PetDogs(const string &s=""):MachinePets(s){};
    string talk()const override{return "wang wang\n";}
};
#include <iostream>
#include <vector>
#include <bits/stdc++.h>
#include "pets.hpp"

void test() {
    using namespace std;

    vector<MachinePets *> pets;

    pets.push_back(new PetCats("miku"));
    pets.push_back(new PetDogs("da huang"));

    for(auto &ptr: pets)
        cout <<ptr->get_nickname() << " says " << ptr->talk() << endl;
}

int main() {
    test();
}

实验四

#pragma once
#include <bits/stdc++.h>
using namespace std;

class Film{
private:
    string name,director,location,year;
public:
    Film(const string &n="",const string &d="",const string &l="",const string &y="");
    friend istream& operator>>(istream& in,Film& film);
    friend ostream& operator<<(ostream& out,const Film& film);
    string get_year() const;
};

Film::Film(const string &n,const string &d,const string &l,const string &y)
{
    this->name=n;
    this->director=d;
    this->location=l;
    this->year=y;
    
}

istream& operator>>(istream& in,Film& film)
{
    in>>film.name>>film.director>>film.location>>film.year;
    return in;
    
}
ostream& operator<<(ostream& out,const Film& film)
{
    cout<<left;
    out<<setw(15)<<"片名:"<<film.name<<endl
       <<setw(15)<<"导演:"<<film.director<<endl
       <<setw(15)<<"制片国家/地区:"<<film.location<<endl
       <<setw(15)<<"上映年份:"<<film.year<<endl;
    return out;
}
string Film::get_year()const
{
    return this->year;
}

bool compare_by_year(const Film film1,const Film film2)
{
    return film1.get_year()<film2.get_year();
}
#include "film.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

void test() {
    using namespace std;
    
    int n;
    cout << "输入电影数目: ";
    cin >> n;

    cout << "录入" << n << "部影片信息" << endl;
    vector<Film> film_lst;
    for(int i = 0; i < n; ++i) {
        Film f;
        cout << string(20, '-') << "" << i+1 << "部影片录入" << string(20, '-') << endl;
        cin >> f;
        film_lst.push_back(f);
    }

    // 按发行年份升序排序
    sort(film_lst.begin(), film_lst.end(), compare_by_year);

    cout << string(20, '=') + "电影信息(按发行年份)" +  string(20, '=')<< endl;
    for(auto &f: film_lst)
        cout << f << endl;
}

int main() {
    test();
}

实验五

#pragma once
#include <bits/stdc++.h>
using namespace std;

template<typename T>
class Complex{
private:
T real,imag;
public:
Complex(const T& r=0,const T& i=0):real(r),imag(i){};
T get_real()const{return real;}
T get_imag()const{return imag;}
Complex operator+=(const Complex c)
{
this->real+=c.real;
this->imag+=c.imag;
return *this;
}
friend Complex operator+(const Complex c1,const Complex c2)
{
return Complex<T>(c1.get_real()+c2.get_real(),c1.get_imag()+c2.get_imag());
}
friend bool operator==(const Complex c1,const Complex c2)
{
return c1.get_real()==c2.get_real() && c1.get_imag()==c2.get_imag();
}
friend istream& operator>>(istream& in,Complex& c)
{
in>>c.real>>c.imag;
return in;
}
friend ostream& operator<<(ostream& out,const Complex& c)
{
if (c.get_imag()>0)
out<<c.get_real()<<"+"<<c.get_imag()<<"i";
else
out<<c.get_real()<<"-"<<-c.get_imag()<<"i";
return out;
}
};

#include "Complex.hpp"
#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::boolalpha;

void test1() {
    Complex<int> c1(2, -5), c2(c1);

    cout << "c1 = " << c1 << endl;
    cout << "c2 = " << c2 << endl;
    cout << "c1 + c2 = " << c1 + c2 << endl;
    
    c1 += c2;
    cout << "c1 = " << c1 << endl;
    cout << boolalpha << (c1 == c2) << endl;
}

void test2() {
    Complex<double> c1, c2;
    cout << "Enter c1 and c2: ";
    cin >> c1 >> c2;
    cout << "c1 = " << c1 << endl;
    cout << "c2 = " << c2 << endl;

    cout << "c1.real = " << c1.get_real() << endl;
    cout << "c1.imag = " << c1.get_imag() << endl;
}

int main() {
    cout << "自定义类模板Complex测试1: " << endl;
    test1();

    cout << endl;

    cout << "自定义类模板Complex测试2: " << endl;
    test2();
}

 实验6

date.h

#ifndef __DATE_H__
#define __DATE_H__
class Date{
private:
    int year;
    int month;
    int day;
    int totalDays;
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 isLeepYear() const{
        return year%4==0 && year%100!=0 ||year%400;
    }
    void show() const;
    int operator-(const Date& date) const{
        return totalDays-date.totalDays;
    }
};
#endif

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"<<endl;
        show();
        cout<<endl;
        exit(-1);
    }
    int years=year-1;
    totalDays=years*365+years/4-year/100+year/400+DAYS_BEFORE_MONTH[month-1]+day;
    if (isLeepYear()&&month>2)totalDays++;
}
int Date::getMaxDay() const
{
    if (isLeepYear()&&month==2)
    {
        return 2;
    }
    else 
    {
        return DAYS_BEFORE_MONTH[month]-DAYS_BEFORE_MONTH[month-1];
    }
}
void Date::show() const
{
    cout<<getYear()<<"-"<<getMonth()<<"-"<<getDay();
}

accumulator.h

#ifndef __ACCUMULATOR_H__
#define __ACCUMULATOR_H__
#include "date.h"
class Accumulator{
private:
    Date lastDate;
    double value;
    double sum;
public:
    Accumulator(const Date &date,double vaule):
        lastDate(date),value(value),sum(0){}
    double getSum(const Date &date) const{
        return sum+value*(date-lastDate);
    }
    void change(const Date &date,double value)
    {
        sum=getSum(date);
        lastDate=date;
        this->value=value;
    }
    void reset(const Date &date,double value)
    {
        lastDate=date;
        this->value=value;
        sum=0;
    }
};
#endif

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:
    Account(const Date &date,const std::string &id);
    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;}
    
    virtual void deposit(const Date &date,double amount,const std::string &desc)=0;
    virtual void withdraw(const Date &date,double amount,const std::string &desc)=0;
    virtual void settle(const Date &date)=0;
    virtual void show() const;
};

class SavingAccount:public Account{
private:
    Accumulator acc;
    double rate;
public:
    SavingAccount(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 getFee() const {return fee;}
    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.cpp

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

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

void Account::record(const Date &date,double amount,const std::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;
} 

SavingAccount::SavingAccount(const Date &date,const std::string &id,double rate):
    Account(date,id),rate(rate),acc(date,0){}
void SavingAccount::deposit(const Date &date,double amount,const std::string &desc)
{
    record(date,amount,desc);
    acc.change(date,getBalance());
}
void SavingAccount::withdraw(const Date &date,double amount,const std::string &desc)
{
    if (amount>getBalance()){
        error("not enough money");
    }else{
        record(date,-amount,desc);
        acc.change(date,getBalance());
    }
}
void SavingAccount::settle(const Date &date)
{
    if (date.getMonth()==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 std::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 std::string &desc)
{
    record(date,amount,desc);
    acc.change(date,getDebt());
}
void CreditAccount::withdraw(const Date &date,double amount,const std::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();
}

main.cpp

#include "account.h"
#include <iostream>
using namespace std;
int main()
{
    Date date(2008,11,1);
    SavingAccount sa1(date,"S3755217",0.015);
    SavingAccount 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]->withdraw(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 prevoius day";
                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;
}

 

posted @ 2024-12-03 20:50  王青松15252129616  阅读(28)  评论(0)    收藏  举报