实验5

实验任务1:

Publisher.hpp:

#pragma once
#include<stdio.h>
class Publsher{
    public:
        Publisher(const std::string &name_="");
        virtual ~Publisher()=default;
    public:
        virtual void publish() const=0;
        virtual void use() const=0;
    protected:
        std::string name;
};
class Book:public publisher{
    public:
        Book(const std::string &name_"",const std::string &author_="");
    public:
        void publish() const override;
        void use() const override;
    private:
        std::string director;    
};
class Film:public publish{
    public:
        Film(const std::string &name_="",const std::string &director_="");
    public:
        void publish()const override;
        void use()const override;
    private:
        std::string director;
};
class Music:public Publisher{
    public:
        Music(const std::string & name_="",const std::string &director_="");
    public:
        void publish()const override;
        void use()const override;
    private:
        std::string artist:    
};

Publisher.cpp:

#include<iostream>
#include<string>
#include"publisher.hpp"
Publisher::publisher(const std::string &name_):name{name_}{
}
Book::Book(const std::string &name_,const std::string &author_):Publisher{name_},author{author_}{
}
void Book::publish()const {
    std::cout<<"Publisher book《"<<name<<"》by"<<author<<"\n"; 
}
void Book::use()const{
     std::cout<<"Reading book《"<<name<<"》by"<<author<<"\n"; 
}
Film::Film(const std::string &name_,const std::string &director):Publishe{name_},director{director_}{
}
void Film::publish()const{
    std::cout<<"Publishing film <"<<name<<">by"<<artist<<'\n';
}
void Film::use()const{
std::cout<<"Listening to music <"<<name<<">by"<<artist<<'\n';
}
Music::Music(const std::string &name_,const std::string &artist_):Publisher{name_},artist{artist_}{
}
Music::publish()const{
    std::cout<<"Publishing musc <"<<name<<">by"<<artist<<'\n';
}
void Music::use()const{
std::cout<<"Listening to music <"<<name<<">by"<<artist<<'\n';
}

test1.cpp

#include <memory>
#include <iostream>
#include <vector>
#include "publisher.hpp"

void test1() {
   std::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(Publisher *ptr: v) {
        ptr->publish();
        ptr->use();
        std::cout << '\n';
        delete ptr;
   }
}

void test2() {
    std::vector<std::unique_ptr<Publisher>> v;

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

    for(const auto &ptr: v) {
        ptr->publish();
        ptr->use();
        std::cout << '\n';
    }
}

void test3() {
    Book book("A Philosophy of Software Design", "John Ousterhout");
    book.publish();
    book.use();
}

int main() {
    std::cout << "运行多态时:纯虚函数,抽象类\n";

    std::cout << "\n测试1: 使用原始指针\n";
    test1();

    std::cout << "\n测试2: 使用智能指针\n";
    test2();

    std::cout << "\n测试3: 直接使用类\n";
    test3();
}

实验结果:

 屏幕截图 2025-12-14 181020

 

 

问题1.1:publisher中不知包括一个纯虚函数,

 

virtual void publish() const=0;
        virtual void use() const=0;

问题1.2:

不能,因为publisher 是一个抽象类,而抽象类不能被实例化只能通过基类指针等方法

问题2.1:

void publish() const override;
        void use() const override;

2.2:

如果没有const 则基类的纯虚函数签名与函数签名不一致会导致编译错误

问题3.1:

声明类型是publisher*其为指向publisher的指针

3.2:

Book   Film   Music

3.3:

使用虚函数是为了删除基类指针时调用派生类析构函数更加安全若删除会导致析构函数不被正常调用

实验任务2:

book.hpp

#pragma once
#include <string>

class Book {
public:
    Book(const std::string &name_, 
         const std::string &author_, 
         const std::string &translator_, 
         const std::string &isbn_, 
         double price_);

    friend std::ostream& operator<<(std::ostream &out, const Book &book);

private:
    std::string name;        
    std::string author;      
    std::string translator;  
    std::string isbn;       
    double price;        
};

book.cpp

#include <iomanip>
#include <iostream>
#include <string>
#include "book.hpp"



Book::Book(const std::string &name_, 
          const std::string &author_, 
          const std::string &translator_, 
          const std::string &isbn_, 
          double price_):name{name_}, author{author_}, translator{translator_}, isbn{isbn_}, price{price_} {
}

std::ostream& operator<<(std::ostream &out, const Book &book) {
    using std::left;
    using std::setw;
    
    out << left;
    out << setw(15) << "书名:" << book.name << '\n'
        << setw(15) << "作者:" << book.author << '\n'
        << setw(15) << "译者:" << book.translator << '\n'
        << setw(15) << "ISBN:" << book.isbn << '\n'
        << setw(15) << "定价:" << book.price;

    return out;
}

booksale.hp#pragma once


#include <string>
#include "book.hpp"
class BookSale {
public:
    BookSale(const Book &rb_, double sales_price_, int sales_amount_);
    int get_amount() const;  
    double get_revenue() const;   
    
    friend std::ostream& operator<<(std::ostream &out, const BookSale &item);

private:
    Book rb;         
    double sales_price;      
    int sales_amount;       
};

 

booksale.cpp

#include <iomanip>
#include <iostream>
#include <string>
#include "booksale.hpp" 
BookSale::BookSale(const Book &rb_, 
                   double sales_price_, 
                   int sales_amount_): rb{rb_}, sales_price{sales_price_}, sales_amount{sales_amount_} {
}

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

double BookSale::get_revenue() const {
    return sales_amount * sales_price;
}


std::ostream& operator<<(std::ostream &out, const BookSale &item) {
    using std::left;
    using std::setw;
    
    out << left;
    out << item.rb << '\n'
        << setw(15) << "售价:" << item.sales_price << '\n'
        << setw(15) << "销售数量" << item.sales_amount << '\n'
        << setw(15) << "营收:" << item.get_revenue();

    return out;
}

task2.cpp

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include "booksale.hpp"

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

void test() {
    using std::cin;
    using std::cout;
    using std::getline;
    using std::sort;
    using std::string;
    using std::vector;
    using std::ws;

    vector<BookSale> sales_records;         /

    int books_number;
    cout << "录入图书数量: ";
    cin >> books_number;

    cout << "录入图书销售记录";
    for(int i = 0; i < books_number; ++i) {
        string name, author, translator, isbn;
        double price;
        cout << string(20, '-') << "第? << i+1 << "本图书信息录入 << string(20, '-') << '\n';
        cout << "录入书名: "; getline(cin>>ws, name);
        cout << " 录入作者"; getline(cin>>ws, author);
        cout << "录入译者 "; getline(cin>>ws, translator);
        cout << "录入isbn: "; getline(cin>>ws, isbn);
        cout << "录入定价: "; cin >> price;

        Book book(name, author, translator, isbn, price);

        double sales_price;
        int sales_amount;

        cout << "录入售价: "; cin >> sales_price;
        cout << "录入销售数量: "; cin >> sales_amount;

        BookSale record(book, sales_price, sales_amount);
        sales_records.push_back(record);
    }

    sort(sales_records.begin(), sales_records.end(), compare_by_amount);
    cout << string(20, '=') <<  "图书销售统计 << string(20, '=') << '\n';
    for(auto &record: sales_records) {
        cout << record << '\n';
        cout << string(40, '-') << '\n';
    }
}

int main() {
    test();
}

实验结果:

 屏幕截图 2025-12-14 181357

 

 

问题1:

重载两处

第一处:

在类Book:

friend std::ostream& operator<<(std::ostream &out, const Book &book);

第2处:

在类booksale:

friend std::ostream& operator<<(std::ostream &out, const BookSale &item);

在book中:

std::ostream& operator<<(std::ostream &out, const Book &book) {
    using std::left;
    using std::setw;
    
    out << left;
    out << setw(15) << "书名:" << book.name << '\n'
        << setw(15) << "作者:" << book.author << '\n'
        << setw(15) << "译者:" << book.translator << '\n'
        << setw(15) << "ISBN:" << book.isbn << '\n'
        << setw(15) << "定价:" << book.price;

    return out;
}

在booksale:

std::ostream& operator<<(std::ostream &out, const BookSale &item) {
    using std::left;
    using std::setw;
    
    out << left;
    out << item.rb << '\n'
        << setw(15) << "售价:" << item.sales_price << '\n'
        << setw(15) << "销售数量" << item.sales_amount << '\n'
        << setw(15) << "营收:" << item.get_revenue();

    return out;
}

问题2:

首先定义比较函数然后用sort算法进行排序

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

实验任务3:

task3_1:

#include <iostream>

class A {
public:
    A(int x0, int y0);
    void display() const;

private:
    int x, y;
};

A::A(int x0, int y0): x{x0}, y{y0} {
}

void A::display() const {
    std::cout << x << ", " << y << '\n';
}


class B {
public:
    B(double x0, double y0);
    void display() const;

private:
    double x, y;
};

B::B(double x0, double y0): x{x0}, y{y0} {
}

void B::display() const {
    std::cout << x << ", " << y << '\n';
}

void test() {
    std::cout << "测试类A: " << '\n';
    A a(3, 4);
    a.display();

    std::cout << "\n测试类B: " << '\n';
    B b(3.2, 5.6);
    b.display();
}

int main() {
    test();
}

实验结果:

屏幕截图 2025-12-14 162447

实验任务3_2:

#include <iostream>
#include <string>

template<typename T>
class X{
public:
    X(T x0, T y0);
    void display();

private:
    T x, y;
};

template<typename T>
X<T>::X(T x0, T y0): x{x0}, y{y0} {
}

template<typename T>
void X<T>::display() {
    std::cout << x << ", " << y << '\n';
}


void test() {
    std::cout << "测试1:用int实例化类模板" << '\n';
    X<int> x1(3, 4);
    x1.display();

    std::cout << "\n测试2:用double实例化测试类模板x" << '\n';
    X<double> x2(3.2, 5.6);
    x2.display();

    std::cout << "\n测试3:用string实例化类的模板x" << '\n';
    X<std::string> x3("hello", "oop");
    x3.display();
}

int main() {
    test();
}

实验结果:

屏幕截图 2025-12-14 162802

实验任务4:

task4.cpp: 

#include <iostream>
#include <memory>
#include <vector>
#include "pet.hpp"

void test1() {
    std::vector<MachinePet *> pets;

    pets.push_back(new PetCat("miku"));
    pets.push_back(new PetDog("da huang"));

    for(MachinePet *ptr: pets) {
        std::cout << ptr->get_nickname() << " says " << ptr->talk() << '\n';
        delete ptr;  
    }   
}

void test2() {
    std::vector<std::unique_ptr<MachinePet>> pets;

    pets.push_back(std::unique_ptr<MachinePet>(new PetCat("miku")));
    pets.push_back(std::unique_ptr<MachinePet>(new PetDog("da huang")));

    for(auto const &ptr: pets)
        std::cout << ptr->get_nickname() << " says " << ptr->talk() << '\n';
}

void test3() {
    const PetCat cat("miku");
    std::cout << cat.get_nickname() << " says " << cat.talk() << '\n';

    const PetDog dog("da huang");
    std::cout << dog.get_nickname() << " says " << dog.talk() << '\n';
}

int main() {
    std::cout << "测试1:使用原始指针\n";
    test1();

    std::cout << "\n测试2:使用智能指针\n";
    test2();

    std::cout << "\n测试3:直接使用类\n";
    test3();
}

 

pet.hpp:

#pragma once
#include <string>
class MachinePet{
    public:
        MachinePet(const std::string&nickname_):nickname(nickname_){
        }
        virtual ~MachinePet()=default;
        std::string get_nickname const()
       {
        return nickname;
       }
       virtual std::string talk()const=0;
    protected:
        std::string nickname;    
};
class PetCat:public MachinePet{
    public:
        PetCat(const std::string&nickname_):MachinePet(nickname_){
        }
        std::string talk()const override{
        return "miao wu-";
        }
};
class PetGog:public MachinePet{
    public:
        PetDog(const std::string&nickname_):MachinePet(nickname_){
        }
        std::string talk() const override{
            return "wang wang-";
        }
    };

实验结果:

屏幕截图 2025-12-14 170845

这里有问题就是实验报告给出的代码中:

pets.push_back(std::make_unique<PetCat>("miku"));
    pets.push_back(std::make_unique<PetDog>("da huang"));

上述代码我的devc++无法运行所以我通过查询改成了:

 pets.push_back(std::unique_ptr<MachinePet>(new PetCat("miku")));
    pets.push_back(std::unique_ptr<MachinePet>(new PetDog("da huang")));

实验任务5:

task5.cpp:

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

void test1() {
    using std::cout;
    using std::boolalpha;
    
    Complex<int> c1(2, -5), c2(c1);

    cout << "c1 = " << c1 << '\n';
    cout << "c2 = " << c2 << '\n';
    cout << "c1 + c2 = " << c1 + c2 << '\n';
    
    c1 += c2;
    cout << "c1 = " << c1 << '\n';
    cout << boolalpha << (c1 == c2) << '\n';
}

void test2() {
    using std::cin;
    using std::cout;

    Complex<double> c1, c2;
    cout << "Enter c1 and c2: ";
    cin >> c1 >> c2;
    cout << "c1 = " << c1 << '\n';
    cout << "c2 = " << c2 << '\n';

    const Complex<double> c3(c1);
    cout << "c3.real = " << c3.get_real() << '\n';
    cout << "c3.imag = " << c3.get_imag() << '\n';
}

int main() {
    std::cout << "自定义类模板complex测试1: \n";
    test1();

    std::cout << "\n自定义类模板complex测试2: \n";
    test2();
}

Complex.hpp:

#pragma once
#include<iostream>
template<typename T>
class Complex{
    private:
        T real;
        T imag;
    public:
        Complex():real(0),imag(0){
        }
        Complex(T r,T i=0):real(r),imag(i){
        }
        Complex(const Complex& other):real(other.real),imag(other.imag){
        }
        T get_real()const {
        return real;} 
        T get_imag()const{
        return imag;}
        Complex& operator+=(const Complex& other)
        {
            real+=other.real;
            imag+=other.imag;
            return *this; 
        }
        Complex operator+(const Complex&other )const{
        return Complex(real+other.real,imag+other.imag);
        }
        Complex operator==(const Complex&other)const{
        return (real==other.real)&&(imag==other.imag);
        }
        friend std::ostream&operator<<(std::ostream& os,const Complex& c){
            os<<c.real;
            if(c.imag>=0)
                os<<"+"<<-c.imag<<"i";
            else
                os<<"-"<<-c.imag<<"i";
                return os;
        }
        friend std::istream&operator>>(std::istream& is,Complex& c)
        {
            is>>c.real>>c.imag;
            return is;
        }
};

实验结果:

屏幕截图 2025-12-14 174917

 

posted @ 2025-12-14 18:14  fuilk  阅读(3)  评论(0)    收藏  举报