实验5

task1

(1)

 1 #pragma once
 2 #include <string>
 3  
 4 class Publisher {
 5 public:
 6     Publisher(const std::string &name_ = "");            
 7     virtual ~Publisher() = default;
 8 public:
 9     virtual void publish() const = 0;                 
10     virtual void use() const = 0;                     
11 protected:
12     std::string name;    
13 };
14 
15 class Book: public Publisher {
16 public:
17     Book(const std::string &name_ = "", const std::string &author_ = "");  
18 public:
19     void publish() const override;        
20     void use() const override;            
21 private:
22     std::string author;          
23 };
24 
25 class Film: public Publisher {
26 public:
27     Film(const std::string &name_ = "", const std::string &director_ = "");   
28 public:
29     void publish() const override;    
30     void use() const override;        
31 private:
32     std::string director;        
33 
34 };
35 class Music:public Publisher{
36 public:
37     Music(const std::string &name_ = "", const std::string &artist_ = "");
38 public:
39     void publish() const override;        
40     void use() const override;            
41 private:
42     std::string artist;  
43 };
publisher.hpp
 1 #include <iostream>
 2 #include <string>
 3 #include "publisher.hpp"
 4 // Publisher类:实现
 5 Publisher::Publisher(const std::string &name_): name {name_} {
 6 }
 7 // Book类: 实现
 8 Book::Book(const std::string &name_ , const std::string &author_ ): Publisher{name_}, 
 9 author{author_} {
10 }
11 void Book::publish() const {
12 std::cout << "Publishing book《" << name << "》 by " << author << '\n';
13 }
14 void Book::use() const {
15 std::cout << "Reading book 《" << name << "》 by " << author << '\n';
16 }
17 // Film类:实现
18 Film::Film(const std::string &name_, const std::string 
19 &director_):Publisher{name_},director{director_} {
20 }
21 void Film::publish() const {
22 std::cout << "Publishing film <" << name << "> directed by " << director << '\n';
23 }
24 void Film::use() const {
25 std::cout << "Watching film <" << name << "> directed by " << director << '\n';
26 }
27 // Music类:实现
28 Music::Music(const std::string &name_, const std::string &artist_): Publisher{name_}, 
29 artist{artist_} {
30 }
31 void Music::publish() const {
32 std::cout << "Publishing music <" << name << "> by " << artist << '\n';
33 }
34 void Music::use() const {
35 std::cout << "Listening to music <" << name << "> by " << artist << '\n';
36 }
publisher.cpp
 1 #include <memory>
 2 #include <iostream>
 3 #include <vector>
 4 #include "publisher.hpp"
 5 void test1() {
 6 std::vector<Publisher *> v;
 7 v.push_back(new Book("Harry Potter", "J.K. Rowling"));
 8 v.push_back(new Film("The Godfather", "Francis Ford Coppola"));
 9 v.push_back(new Music("Blowing in the wind", "Bob Dylan"));
10 for(Publisher *ptr: v) {
11 ptr->publish();
12 ptr->use();
13 std::cout << '\n';
14 delete ptr;
15     }
16 }
17 /*void test2() {
18 std::vector<std::unique_ptr<Publisher>> v;
19 v.push_back(std::make_unique<Book>("Harry Potter", "J.K. Rowling"));
20 v.push_back(std::make_unique<Film>("The Godfather", "Francis Ford Coppola"));
21 v.push_back(std::make_unique<Music>("Blowing in the wind", "Bob Dylan"));
22 for(const auto &ptr: v) {
23 ptr->publish();
24 ptr->use();
25 std::cout << '\n';
26     }
27 }*/
28 void test3() {
29 Book book("A Philosophy of Software Design", "John Ousterhout");
30 book.publish();
31 book.use();
32 }
33 int main() {
34 std::cout << "运行时多态:纯虚函数、抽象类\n";
35 std::cout << "\n测试1: 使用原始指针\n";
36 test1();
37 //std::cout << "\n测试2: 使用智能指针\n";
38 //test2();
39 std::cout << "\n测试3: 直接使用类\n";
40 test3();
41 }
task1.cpp

(2)运行结果

image

 (3)回答问题

1.1)有纯虚函数的类是抽象类。

virtual void publish() const = 0;

virtual void use() const = 0;

2)不能编译通过。因为Publisher类是抽象类,不能定义变量p。

2.1)

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

2)报错信息是声明与定义不匹配。

image

3.1)声明类型为Publisher*。指向基类的指针。

2)Book类对象,Film类对象,Music类对象。

3)可能存在内存泄露,派生类清除不干净。

task2

(1)

 1 #pragma once
 2 #include <string>
 3 // 图书描述信息类Book: 声明
 4 class Book {
 5 public:
 6     Book(const std::string &name_, 
 7          const std::string &author_, 
 8          const std::string &translator_, 
 9          const std::string &isbn_, 
10          double price_);
11     friend std::ostream& operator<<(std::ostream &out, const Book &book);
12 private:
13     std::string name;        // 书名
14     std::string author;      // 作者
15     std::string translator;  // 译者
16     std::string isbn;        // isbn号
17     double price;        // 定价
18 };
book.hpp
 1 #include <iomanip>
 2 #include <iostream>
 3 #include <string>
 4 #include "book.hpp"
 5 // 图书描述信息类Book: 实现
 6 Book::Book(const std::string &name_, 
 7           const std::string &author_, 
 8           const std::string &translator_, 
 9           const std::string &isbn_, 
10           double price_):name{name_}, author{author_}, translator{translator_}, 
11 isbn{isbn_}, price{price_} {
12 }
13 // 运算符<<重载实现
14 std::ostream& operator<<(std::ostream &out, const Book &book) {
15     using std::left;
16     using std::setw;
17     
18     out << left;
19     out << setw(15) << "书名:" << book.name << '\n'
20         << setw(15) << "作者:" << book.author << '\n'
21         << setw(15) << "译者:" << book.translator << '\n'
22         << setw(15) << "ISBN:" << book.isbn << '\n'
23         << setw(15) << "定价:" << book.price;
24     return out;
25 }
book.cpp
 1 #pragma once
 2 #include <string>
 3 #include "book.hpp"
 4 // 图书销售记录类BookSales:声明
 5 class BookSale {
 6 public:
 7     BookSale(const Book &rb_, double sales_price_, int sales_amount_);
 8     int get_amount() const;   // 返回销售数量
 9     double get_revenue() const;   // 返回营收
10     
11     friend std::ostream& operator<<(std::ostream &out, const BookSale &item);
12 private:
13     Book rb;         
14     double sales_price;      // 售价
15     int sales_amount;       // 销售数量
16 };
booksale.hpp
 1 #include <iomanip>
 2 #include <iostream>
 3 #include <string>
 4 #include "booksale.hpp"
 5 // 图书销售记录类BookSales:实现
 6 BookSale::BookSale(const Book &rb_, 
 7 double sales_price_, 
 8 int sales_amount_): rb{rb_}, sales_price{sales_price_}, 
 9 sales_amount{sales_amount_} {
10 }
11 int BookSale::get_amount() const {
12 return sales_amount;
13 }
14 double BookSale::get_revenue() const {
15 return sales_amount * sales_price;
16 }
17 // 运算符<<重载实现
18 std::ostream& operator<<(std::ostream &out, const BookSale &item) {
19 using std::left;
20 using std::setw;
21 out << left;
22 out << item.rb << '\n'
23 << setw(15) << "售价:" << item.sales_price << '\n'
24 << setw(15) << "销售数量:" << item.sales_amount << '\n'
25 << setw(15) << "营收:" << item.get_revenue();
26 return out;
27 }
booksale.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 void test() {
11 using namespace std;
12  vector<BookSale> sales_lst;         // 存放图书销售记录
13      int books_number;
14     cout << "录入图书数量: ";
15     cin >> books_number;
16     cout << "录入图书销售记录" << endl;
17     for(int i = 0; i < books_number; ++i) {
18         string name, author, translator, isbn;
19         float price;
20         cout << string(20, '-') << "" << i+1 << "本图书信息录入" << string(20, '-') << 
21 endl;
22         cout << "录入书名: "; cin >> name;
23         cout << "录入作者: "; cin >> author;
24         cout << "录入译者: "; cin >> translator;
25         cout << "录入isbn: "; cin >> isbn;
26         cout << "录入定价: "; cin >> price;
27         Book book(name, author, translator, isbn, price);
28         float sales_price;
29         int sales_amount;
30         cout << "录入售价: "; cin >> sales_price;
31         cout << "录入销售数量: "; cin >> sales_amount;
32         BookSale record(book, sales_price, sales_amount);
33         sales_lst.push_back(record);
34     }
35     // 按销售册数排序
36     sort(sales_lst.begin(), sales_lst.end(), compare_by_amount);
37     // 按销售册数降序输出图书销售信息
38     cout << string(20, '=') <<  "图书销售统计" << string(20, '=') << endl;
39     for(auto &t: sales_lst) {
40         cout << t << endl;
41         cout << string(40, '-') << endl;
42     }
43 }
44 int main() {
45     test();
46 }
task2.cpp

(2)运行结果

 

image

 (3)回答问题

1.1)Book类中重载<<,Booksale类中重载<<

2)

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;
}

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;
}

2.1)

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

task3

(1)

 1 #include <iostream>
 2 // 类A的定义
 3 class A {
 4 public:
 5 A(int x0, int y0);
 6 void display() const;
 7 private:
 8 int x, y;
 9 };
10 A::A(int x0, int y0): x{x0}, y{y0} {
11 }
12 void A::display() const {
13 std::cout << x << ", " << y << '\n';
14 }
15 // 类B的定义
16 class B {
17 public:
18 B(double x0, double y0);
19 void display() const;
20 private:
21 double x, y;
22 };
23 B::B(double x0, double y0): x{x0}, y{y0} {
24 }
25 void B::display() const {
26 std::cout << x << ", " << y << '\n';
27 }
28 void test() {
29 std::cout << "测试类A: " << '\n';
30 A a(3, 4);
31 a.display();
32 std::cout << "\n测试类B: " << '\n';
33 B b(3.2, 5.6);
34 b.display();
35 }
36 int main() {
37 test();
38 }
task3_1.cpp

运行结果

image

(2)

 1 #include <iostream>
 2 #include <string>
 3 // 定义类模板
 4 template<typename T>
 5 class X{
 6 public:
 7 X(T x0, T y0);
 8 void display();
 9 private:
10 T x, y;
11 };
12 template<typename T>
13 X<T>::X(T x0, T y0): x{x0}, y{y0} {
14 }
15 template<typename T>
16 void X<T>::display() {
17 std::cout << x << ", " << y << '\n';
18 }
19 void test() {
20 std::cout << "测试1: 用int实例化类模板X" << '\n';
21 X<int> x1(3, 4);
22 x1.display();
23 std::cout << "\n测试2: 用double实例化类模板X" << '\n';
24 X<double> x2(3.2, 5.6);
25 x2.display();
26 std::cout << "\n测试3: 用string实例化类模板X" << '\n';
27 X<std::string> x3("hello", "oop");
28 x3.display();
29 }
30 int main() {
31 test();
32 }
task3_2.cpp

运行结果

image

 task4

(1)

 1 include<string>
 2 #include<iostream>
 3 
 4 class  MachinePet{
 5 public:
 6     virtual ~MachinePet()=default;
 7     virtual std::string get_nickname()const=0;    
 8     virtual std::string talk() const=0;
 9 };
10 
11 class PetCat:public MachinePet{
12 public:
13     PetCat(const std::string &nickname_):nickname(nickname_){}
14 public:
15     std::string get_nickname()const override{return nickname;}
16     std::string talk()const override{return"miao wu~";}
17 private:
18     std::string nickname;
19 };
20 class PetDog:public MachinePet{
21 public:
22     PetDog(const std::string &nickname_):nickname(nickname_){}
23 public:
24     std::string get_nickname()const override{return nickname;}
25     std::string talk()const override{return "wang wang~";}
26 private:
27     std::string nickname;
28 };
pets.hpp
 1 #include <iostream>
 2 #include <memory>
 3 #include <vector>
 4 #include "pets.hpp"
 5 void test1() {
 6 std::vector<MachinePet *> pets;
 7 pets.push_back(new PetCat("miku"));
 8 pets.push_back(new PetDog("da huang"));
 9 for(MachinePet *ptr: pets) {
10 std::cout << ptr->get_nickname() << " says " << ptr->talk() << '\n';
11 delete ptr;  // 须手动释放资源
12     }   
13 }
14 /*void test2() {
15 std::vector<std::unique_ptr<MachinePet>> pets;
16 pets.push_back(std::make_unique<PetCat>("miku"));
17 pets.push_back(std::make_unique<PetDog>("da huang"));
18 for(auto const &ptr: pets)
19     std::cout << ptr->get_nickname() << " says " << ptr->talk() << '\n';
20 }*/
21 void test3() {
22 // MachinePet pet("little cutie");   // 编译报错:无法定义抽象类对象
23 const PetCat cat("miku");
24 std::cout << cat.get_nickname() << " says " << cat.talk() << '\n';
25 const PetDog dog("da huang");
26 std::cout << dog.get_nickname() << " says " << dog.talk() << '\n';
27 }
28 int main() {
29 std::cout << "测试1: 使用原始指针\n";
30 test1();
31 //std::cout << "\n测试2: 使用智能指针\n";
32 //test2();
33 std::cout << "\n测试3: 直接使用类\n";
34 test3();
35 }
task4.cpp

(2)运行结果

image

task 5

 (1)

 1 #pragma once
 2 #include<iostream>
 3 
 4 //template<typename T>
 5 //class Complex;
 6 //template<typename T>
 7 //std::ostream& operator<<(std::ostream &out,const Complex<T> &c);
 8 //template<typename T>
 9 //std::istream& operator>>(std::istream &in,Complex<T> &c);
10 template<typename T>
11 class Complex{
12 public:
13     Complex(T x0=0,T y0=0);
14     T get_real()const{return x;}
15     T get_imag()const{return y;}
16     friend std::ostream& operator<<(std::ostream &out,const Complex<T> &c);
17     friend std::istream& operator>>(std::istream &in,Complex<T> &c);
18     Complex operator+(const Complex &c)const;
19     Complex& operator+=(const Complex &c);
20     bool operator==(const Complex &c)const;
21 private:
22     T x,y;    
23 };
24 
25 template<typename T>
26 Complex<T>::Complex(T x0,T y0):x(x0),y(y0){}
27 
28 template<typename T>
29 Complex<T> Complex<T>::operator+(const Complex<T> &c)const
30 {
31     return Complex<T>(x+c.x,y+c.y);
32 }
33 
34 template<typename T>
35 Complex<T>& Complex<T>::operator+=(const Complex<T> &c)
36 {
37     x+=c.x;
38     y+=c.y;
39     return *this; 
40 }
41 
42 template<typename T>
43 std::ostream& operator<<(std::ostream &out,const Complex<T> &c){
44     out<<c.x;
45     if(c.y>=0) 
46         out<<"+"<<c.y<<"i";
47     else
48         out<<c.y<<"i";
49     return out;
50 }
51 
52 template<typename T>
53 std::istream& operator>>(std::istream &in,Complex<T> &c){
54     in>>c.x>>c.y;
55     return in;
56 }
57 
58 template<typename T>
59 bool Complex<T>::operator==(const Complex<T> &c)const
60 {
61     return (x==c.x)&&(y==c.y);
62 }
Complex.hpp
 1 #include <iostream>
 2 #include "Complex.hpp"
 3 void test1() {
 4 using std::cout;
 5 using std::boolalpha;
 6 Complex<int> c1(2, -5), c2(c1);
 7 cout << "c1 = " << c1 << '\n';
 8 cout << "c2 = " << c2 << '\n';
 9 cout << "c1 + c2 = " << c1 + c2 << '\n';
10 c1 += c2;
11 cout << "c1 = " << c1 << '\n';
12 cout << boolalpha << (c1 == c2) << '\n';
13 }
14 void test2() {
15 using std::cin;
16 using std::cout;
17 Complex<double> c1, c2;
18 cout << "Enter c1 and c2: ";
19 cin >> c1 >> c2;
20 cout << "c1 = " << c1 << '\n';
21 cout << "c2 = " << c2 << '\n';
22 const Complex<double> c3(c1);
23 cout << "c3.real = " << c3.get_real() << '\n';
24 cout << "c3.imag = " << c3.get_imag() << '\n';
25 }
26 int main() {
27 std::cout << "自定义类模板Complex测试1: \n";
28 test1();
29 std::cout << "\n自定义类模板Complex测试2: \n";
30 test2();
31 }
task5.cpp

(2)运行结果

image

 

posted @ 2025-12-10 21:11  deep_l  阅读(3)  评论(0)    收藏  举报