c++ 4

##task1

#代码

  1 #include <algorithm>
  2 #include <array>
  3 #include <cstdlib>
  4 #include <iomanip>
  5 #include <iostream>
  6 #include <numeric>
  7 #include <string>
  8 #include <vector>
  9 
 10 #include "GradeCalc.hpp"
 11 
 12 GradeCalc::GradeCalc(const std::string &cname):course_name{cname},is_dirty{true} {
 13     counts.fill(0);
 14     rates.fill(0);   
 15 }
 16 
 17 void GradeCalc::input(int n) {
 18     if(n < 0) {
 19         std::cerr << "无效输入! 人数不能为负数\n";
 20         std::exit(1);
 21     }
 22 
 23     grades.reserve(n);
 24 
 25     int grade;
 26 
 27     for(int i = 0; i < n;) {
 28         std::cin >> grade;
 29 
 30         if(grade < 0 || grade > 100) {
 31             std::cerr << "无效输入! 分数须在[0,100]\n";
 32             continue;
 33         }
 34         
 35         grades.push_back(grade);
 36         ++i;
 37     }
 38 
 39     is_dirty = true;  // 设置脏标记:成绩信息有变更
 40 }
 41 
 42 void GradeCalc::output() const {
 43     for(auto grade: grades)
 44         std::cout << grade << ' ';
 45     std::cout << std::endl;
 46 }
 47     
 48 void GradeCalc::sort(bool ascending) {
 49     if(ascending)
 50         std::sort(grades.begin(), grades.end());
 51     else
 52         std::sort(grades.begin(), grades.end(), std::greater<int>());
 53 }
 54 
 55 int GradeCalc::min() const {
 56     if(grades.empty())
 57         return -1;
 58 
 59     auto it = std::min_element(grades.begin(), grades.end());
 60     return *it;
 61 }
 62 
 63 int GradeCalc::max() const {
 64     if(grades.empty()) 
 65         return -1;
 66 
 67     auto it = std::max_element(grades.begin(), grades.end());
 68     return *it;
 69 }
 70 
 71 double GradeCalc::average() const {
 72     if(grades.empty())
 73         return 0.0;
 74 
 75     double avg = std::accumulate(grades.begin(), grades.end(), 0.0)/grades.size();
 76     return avg;
 77 }
 78 
 79 void GradeCalc::info() {
 80     if(is_dirty) 
 81        compute();
 82 
 83     std::cout << "课程名称:\t" << course_name << std::endl;
 84     std::cout << "平均分:\t" << std::fixed << std::setprecision(2) << average() << std::endl;
 85     std::cout << "最高分:\t" << max() << std::endl;
 86     std::cout << "最低分:\t" << min() << std::endl;
 87 
 88     const std::array<std::string, 5> grade_range{"[0, 60) ", 
 89                                            "[60, 70)", 
 90                                            "[70, 80)",
 91                                            "[80, 90)", 
 92                                            "[90, 100]"};
 93     
 94     for(int i = static_cast<int>(grade_range.size())-1; i >= 0; --i)
 95         std::cout << grade_range[i] << "\t: " << counts[i] << "人\t"
 96                   << std::fixed << std::setprecision(2) << rates[i]*100 << "%\n";
 97 }
 98 
 99 void GradeCalc::compute() {
100     if(grades.empty())
101         return;
102 
103     counts.fill(0); 
104     rates.fill(0.0);
105 
106     // 统计各分数段人数
107     for(auto grade:grades) {
108         if(grade < 60)
109             ++counts[0];        // [0, 60)
110         else if (grade < 70)
111             ++counts[1];        // [60, 70)
112         else if (grade < 80)
113             ++counts[2];        // [70, 80)
114         else if (grade < 90)
115             ++counts[3];        // [80, 90)
116         else
117             ++counts[4];        // [90, 100]
118     }
119 
120     // 统计各分数段比例
121     for(size_t i = 0; i < rates.size(); ++i)
122         rates[i] = counts[i] * 1.0 / grades.size();
123     
124     is_dirty = false;  // 更新脏标记
125 }
 1 #pragma once
 2 
 3 #include <vector>
 4 #include <array>
 5 #include <string>
 6 
 7 class GradeCalc {
 8 public:
 9     GradeCalc(const std::string &cname);      
10     void input(int n);                         // 录入n个成绩
11     void output() const;                      // 输出成绩
12     void sort(bool ascending = false);        // 排序 (默认降序)
13     int min() const;                          // 返回最低分(如成绩未录入,返回-1)
14     int max() const;                          // 返回最高分 (如成绩未录入,返回-1)
15     double average() const;                   // 返回平均分 (如成绩未录入,返回0.0)
16     void info();                      // 输出课程成绩信息 
17 
18 private:
19     void compute();     // 成绩统计
20 
21 private:
22     std::string course_name;     // 课程名
23     std::vector<int> grades;     // 课程成绩
24     std::array<int, 5> counts;      // 保存各分数段人数([0, 60), [60, 70), [70, 80), [80, 90), [90, 100]
25     std::array<double, 5> rates;    // 保存各分数段人数占比 
26     bool is_dirty;      // 脏标记,记录是否成绩信息有变更
27 };
 1 #include <iostream>
 2 #include <string>
 3 #include "GradeCalc.hpp"
 4 
 5 void test() {
 6     GradeCalc c1("OOP");
 7 
 8     std::cout << "录入成绩:\n";
 9     c1.input(5);
10 
11     std::cout << "输出成绩:\n";
12     c1.output();
13 
14     std::cout << "排序后成绩:\n";
15     c1.sort(); c1.output();
16 
17     std::cout << "*************成绩统计信息*************\n";
18     c1.info();
19 
20 }
21 
22 int main() {
23     test();
24 }

#运行结果

image

 #问题回答

1. std::string course_name:存储课程名称,作为GradeCalc对象的标识信息。

std::vector<int> grades:动态存储所有学生的成绩数据,支持成绩的增删改查操作。

std::array<int,5> counts:固定存储5个分数段的人数统计([0,60)、[60,70)、[70,80)、[80,90)、[90,100])。

std::array<double,5> rates:固定存储5个分数段的占比率,用于成绩分布分析。

bool is_dirty:脏标记,用于标识成绩统计信息是否需要重新计算。

2.不合法  GradeCalc类中没有名为 push_back 的公有成员函数

3.1次  is_dirty作用是为了避免重复计算,提高效率

不需要 update_grade不直接调用compute,避免不必要的计算

4.要增加"中位数"统计功能而不新增数据成员,我们需要在现有的函数中添加计算逻辑   在info()函数中添加

 1 double median() const;  
 2 
 3 
 4 double GradeCalc::median() const {
 5     if (grades.empty()) {
 6         return 0.0;  
 7     }
 8     
 9     std::vector<int> sorted_grades = grades;
10     std::sort(sorted_grades.begin(), sorted_grades.end());
11     
12     size_t n = sorted_grades.size();
13     
14     if (n % 2 == 1) {
15         // 奇数个成绩:取中间值
16         return sorted_grades[n / 2];
17     } else {
18         // 偶数个成绩:取中间两个值的平均
19         return (sorted_grades[n / 2 - 1] + sorted_grades[n / 2]) / 2.0;
20     }
21 }
22 
23 // 修改info()函数,添加中位数显示
24 void GradeCalc::info() {
25     if (is_dirty) {
26         compute();
27     }
28     
29     std::cout << "课程名称:\t" << course_name << std::endl;
30     std::cout << "平均分:\t" << std::fixed << std::setprecision(2) << average() << std::endl;
31     std::cout << "中位数:\t" << std::fixed << std::setprecision(2) << median() << std::endl;  
32     std::cout << "最高分:\t" << max() << std::endl;
33     std::cout << "最低分:\t" << min() << std::endl;
34 
35 }

5.不能去掉  以下场景会引发统计错误:当成绩数据发生变化后再次调用  或 成绩被修改后重新录入 等

6.程序功能没有影响  去掉会导致vector在push_back时可能触发多次内存重新分配和元素拷贝,增加时间开销,降低性能。

 

##task2

#代码

 1 #pragma once
 2 #include <array>
 3 #include <string>
 4 #include <vector>
 5 
 6 
 7 class GradeCalc: private std::vector<int> {
 8 public:
 9 GradeCalc(const std::string &cname);
10 void input(int n); // 录入n个成绩
11 void output() const; // 输出成绩
12 void sort(bool ascending = false); // 排序 (默认降序)
13 int min() const; // 返回最低分
14 int max() const; // 返回最高分
15 double average() const; // 返回平均分
16 void info(); // 输出成绩统计信息
17 
18 private:
19 void compute(); // 计算成绩统计信息
20 
21 private:
22 std::string course_name; // 课程名
23 std::array<int, 5> counts; // 保存各分数段人数([0, 60), [60, 70), [70, 80), [80,90), [90, 100]
24 std::array<double, 5> rates; // 保存各分数段占比
25 bool is_dirty; // 脏标记,记录是否成绩信息有变更
26 };
  1 #include <algorithm>
  2 #include <array>
  3 #include <cstdlib>
  4 #include <iomanip>
  5 #include <iostream>
  6 #include <numeric>
  7 #include <string>
  8 #include <vector>
  9 #include "GradeCalc.hpp"
 10 
 11 GradeCalc::GradeCalc(const std::string &cname): course_name{cname}, is_dirty{true}{
 12 counts.fill(0);
 13 rates.fill(0);
 14 }
 15 void GradeCalc::input(int n) {
 16 if(n < 0) {
 17 std::cerr << "无效输入! 人数不能为负数\n";
 18 return;
 19 }
 20 this->reserve(n);
 21 int grade;
 22 for(int i = 0; i < n;) {
 23 std::cin >> grade;
 24 if(grade < 0 || grade > 100) {
 25 std::cerr << "无效输入! 分数须在[0,100]\n";
 26 continue;
 27 }
 28 this->push_back(grade);
 29 ++i;
 30 }
 31 is_dirty = true;
 32 }
 33 
 34 
 35 void GradeCalc::output() const {
 36 for(auto grade: *this)
 37 std::cout << grade << ' ';
 38 std::cout << std::endl;
 39 }
 40 void GradeCalc::sort(bool ascending) {
 41 if(ascending)
 42 std::sort(this->begin(), this->end());
 43 else
 44 std::sort(this->begin(), this->end(), std::greater<int>());
 45 }
 46 int GradeCalc::min() const {
 47 if(this->empty())
 48 return -1;
 49 return *std::min_element(this->begin(), this->end());
 50 }
 51 int GradeCalc::max() const {
 52 if(this->empty())
 53 return -1;
 54 return *std::max_element(this->begin(), this->end());
 55 }
 56 double GradeCalc::average() const {
 57 if(this->empty())
 58 return 0.0;
 59 double avg = std::accumulate(this->begin(), this->end(), 0.0) / this->size();
 60 return avg;
 61 }
 62 void GradeCalc::info() {
 63 if(is_dirty)
 64 compute();
 65 std::cout << "课程名称:\t" << course_name << std::endl;
 66 std::cout << "平均分:\t" << std::fixed << std::setprecision(2) << average() <<
 67 std::endl;
 68 std::cout << "最高分:\t" << max() << std::endl;
 69 std::cout << "最低分:\t" << min() << std::endl;
 70 const std::array<std::string, 5> grade_range{"[0, 60) ",
 71     "[60, 70)",
 72 "[70, 80)",
 73 "[80, 90)",
 74 "[90, 100]"};
 75 for(int i = grade_range.size()-1; i >= 0; --i)
 76 std::cout << grade_range[i] << "\t: " << counts[i] << "人\t"
 77 << std::fixed << std::setprecision(2) << rates[i]*100 << "%\n";
 78 }
 79 void GradeCalc::compute() {
 80 if(this->empty())
 81 return;
 82 counts.fill(0);
 83 rates.fill(0);
 84 // 统计各分数段人数
 85 for(int grade: *this) {
 86 if(grade < 60)
 87 ++counts[0]; // [0, 60)
 88 else if (grade < 70)
 89 ++counts[1]; // [60, 70)
 90 else if (grade < 80)
 91 ++counts[2]; // [70, 80)
 92 else if (grade < 90)
 93 ++counts[3]; // [80, 90)
 94 else
 95 ++counts[4]; // [90, 100]
 96 }
 97 // 统计各分数段比例
 98 for(int i = 0; i < rates.size(); ++i)
 99 rates[i] = counts[i] * 1.0 / this->size();
100 is_dirty = false;
101 }
 1 #include <iostream>
 2 #include <string>
 3 #include "GradeCalc.hpp"
 4 void test() {
 5 GradeCalc c1("OOP");
 6 std::cout << "录入成绩:\n";
 7 c1.input(5);
 8 std::cout << "输出成绩:\n";
 9 c1.output();
10 std::cout << "排序后成绩:\n";
11 c1.sort(); c1.output();
12 std::cout << "*************成绩统计信息*************\n";
13 c1.info();
14 }
15 int main() {
16 test();
17 }

 #运行结果

image

 #问题回答

1.class GradeCalc: private std::vector<int> 

2.当前继承方式下,基类vector的接口不会自动成为GradeCalc的接口。

 测试代码编译结果:不能通过    原因: 由于使用的是私有继承(private继承),基类vector的所有公有和保护成员在GradeCalc类中都变成了私有成员,外部无法直接访问。

 3.组合方式:数据访问通过明确的成员变量接口,封装性更强    继承方式:数据访问通过继承的基类接口,耦合度更高

4.我认为组合方案更适合成绩计算这个场景。

理由:封装性更好:组合方式将成绩数据完全封装在GradeCalc内部,外部无法直接操作grades向量     接口控制更精确:GradeCalc可以精确控制哪些操作对外暴露,避免vector的不必要接口污染

 

##task3

#代码

 1 #include <algorithm>
 2 #include <cctype>
 3 #include <iostream>
 4 #include <string>
 5 #include "Graph.hpp"
 6 // Circle类实现
 7 void Circle::draw() { std::cout << "draw a circle...\n"; }
 8 // Triangle类实现
 9 void Triangle::draw() { std::cout << "draw a triangle...\n"; }
10 // Rectangle类实现
11 void Rectangle::draw() { std::cout << "draw a rectangle...\n"; }
12 // Canvas类实现
13 void Canvas::add(const std::string& type) {
14 Graph* g = make_graph(type);
15 if (g)
16 graphs.push_back(g);
17 }
18 void Canvas::paint() const {
19 for (Graph* g : graphs)
20 g->draw();
21 }
22 Canvas::~Canvas() {
23 for (Graph* g : graphs)
24 delete g;
25 }
26 // 工具函数实现
27 // 字符串 → 枚举转换
28 GraphType str_to_GraphType(const std::string& s) {
29 std::string t = s;
30 std::transform(s.begin(), s.end(), t.begin(),
31 [](unsigned char c) { return std::tolower(c);});
32 if (t == "circle")
33 return GraphType::circle;
34 if (t == "triangle")
35 return GraphType::triangle;
36 if (t == "rectangle")
37 return GraphType::rectangle;
38 return GraphType::circle; // 缺省返回
39 }
40 // 创建图形,返回堆对象指针
41 Graph* make_graph(const std::string& type) {
42 switch (str_to_GraphType(type)) {
43 case GraphType::circle: return new Circle;
44 case GraphType::triangle: return new Triangle;
45 case GraphType::rectangle: return new Rectangle;
46 default: return nullptr;
47 }
48 }
 1 #pragma once
 2 
 3 #include <string>
 4 #include <vector>
 5 enum class GraphType {circle, triangle, rectangle};
 6 // Graph类定义
 7 class Graph {
 8 public:
 9 virtual void draw() {}
10 virtual ~Graph() = default;
11 };
12 // Circle类声明
13 class Circle : public Graph {
14 public:
15 void draw();
16 };
17 // Triangle类声明
18 class Triangle : public Graph {
19 public:
20 void draw();
21 };
22 // Rectangle类声明
23 class Rectangle : public Graph {
24 public:
25 void draw();
26 };
27 // Canvas类声明
28 class Canvas {
29 public:
30 void add(const std::string& type); // 根据字符串添加图形
31 void paint() const; // 使用统一接口绘制所有图形
32 ~Canvas(); // 手动释放资源
33 private:
34 std::vector<Graph*> graphs;
35 };
36 // 4. 工具函数
37 GraphType str_to_GraphType(const std::string& s); // 字符串转枚举类型
38 Graph* make_graph(const std::string& type); // 创建图形,返回堆对象指针
 1 #include <string>
 2 #include "Graph.hpp"
 3 void test() {
 4 Canvas canvas;
 5 canvas.add("circle");
 6 canvas.add("triangle");
 7 canvas.add("rectangle");
 8 canvas.paint();
 9 }
10 int main() {
11 test();
12 }

#运行结果

image

 #问题回答

1.(1)std::vector<Graph*> graphs;   存储指向各种图形对象的指针,实现Canvas对图形对象的容器管理(2)class Circle : public Graph        class Triangle : public Graph       class rectangle : public Graph 

2.(1)如果draw未声明为虚函数,Canvas::paint()中的g->draw()将调用Graph基类的draw方法(空实现),而不是具体子类的draw方法,导致所有图形都无法正确绘制

(2)导致对象切片(object slicing),派生类的特有信息丢失,多态机制失效,所有图形对象都被当作Graph基类处理

(3)当通过基类指针删除派生类对象时,只会调用基类的析构函数,派生类的析构函数不会被调用,导致内存泄漏和资源未正确释放。

3.(1)Graph.hpp文件:在GraphType枚举中添加star成员      新增Star类声明:class Star : public Graph { public: void draw(); }

Graph.cpp文件:实现Star::draw()方法     在str_to_GraphType函数中添加"star"字符串处理    在make_graph函数中添加GraphType::star分支

4.(1)在Canvas的析构函数中被释放

(2)利:简单直观,学习成本低 性能开销小 兼容性好,适用于各种C++环境

弊:内存泄漏风险:忘记delete会导致内存泄漏悬空   指针风险:可能访问已释放的内存

异常安全问题:异常发生时资源可能无法正确释放

 

##task4

#代码

  1 #include <iostream>
  2 #include <vector>
  3 #include <algorithm>
  4 #include "Toy.hpp"
  5 
  6 using namespace std;
  7 
  8 // Toy基类实现
  9 Toy::Toy(const string& name, ToyType type, double price, int battery)
 10     : name(name), type(type), price(price), battery_level(battery), is_on(false) {}
 11 
 12 void Toy::displayInfo() const {
 13     cout << "名称: " << name 
 14          << " | 类型: " << toyTypeToString(type)
 15          << " | 价格: ¥" << price
 16          << " | 电量: " << battery_level << "%"
 17          << " | 状态: " << (is_on ? "开启" : "关闭") << endl;
 18 }
 19 
 20 void Toy::turnOn() {
 21     if (battery_level > 0) {
 22         is_on = true;
 23         cout << name << " 已开启!" << endl;
 24     } else {
 25         cout << name << " 电量不足,无法开启!" << endl;
 26     }
 27 }
 28 
 29 void Toy::turnOff() {
 30     is_on = false;
 31     cout << name << " 已关闭。" << endl;
 32 }
 33 
 34 void Toy::charge(int amount) {
 35     battery_level = min(100, battery_level + amount);
 36     cout << name << " 充电完成,当前电量: " << battery_level << "%" << endl;
 37 }
 38 
 39 // TeddyBear实现
 40 TeddyBear::TeddyBear(const string& name, double price) 
 41     : Toy(name, ToyType::BEAR, price) {}
 42 
 43 void TeddyBear::specialFunction() {
 44     if (!is_on) {
 45         cout << name << " 未开启,无法使用特异功能!" << endl;
 46         return;
 47     }
 48     if (battery_level < 10) {
 49         cout << name << " 电量不足,无法使用特异功能!" << endl;
 50         return;
 51     }
 52     battery_level -= 5;
 53     hug();
 54 }
 55 
 56 void TeddyBear::hug() {
 57     cout << " " << name << " 给你一个温暖的拥抱!感觉好舒服~" << endl;
 58 }
 59 
 60 // Rabbit实现
 61 Rabbit::Rabbit(const string& name, double price) 
 62     : Toy(name, ToyType::RABBIT, price) {}
 63 
 64 void Rabbit::specialFunction() {
 65     if (!is_on) {
 66         cout << name << " 未开启,无法使用特异功能!" << endl;
 67         return;
 68     }
 69     if (battery_level < 15) {
 70         cout << name << " 电量不足,无法使用特异功能!" << endl;
 71         return;
 72     }
 73     battery_level -= 10;
 74     jump();
 75 }
 76 
 77 void Rabbit::jump() {
 78     cout << " " << name << " 蹦蹦跳跳!跳了3米高!" << endl;
 79 }
 80 
 81 // Dog实现
 82 Dog::Dog(const string& name, double price) 
 83     : Toy(name, ToyType::DOG, price) {}
 84 
 85 void Dog::specialFunction() {
 86     if (!is_on) {
 87         cout << name << " 未开启,无法使用特异功能!" << endl;
 88         return;
 89     }
 90     if (battery_level < 8) {
 91         cout << name << " 电量不足,无法使用特异功能!" << endl;
 92         return;
 93     }
 94     battery_level -= 8;
 95     bark();
 96 }
 97 
 98 void Dog::bark() {
 99     cout << " " << name << " 汪汪叫!声音洪亮!" << endl;
100 }
101 
102 // Cat实现
103 Cat::Cat(const string& name, double price) 
104     : Toy(name, ToyType::CAT, price) {}
105 
106 void Cat::specialFunction() {
107     if (!is_on) {
108         cout << name << " 未开启,无法使用特异功能!" << endl;
109         return;
110     }
111     if (battery_level < 6) {
112         cout << name << " 电量不足,无法使用特异功能!" << endl;
113         return;
114     }
115     battery_level -= 6;
116     purr();
117 }
118 
119 void Cat::purr() {
120     cout << "" << name << " 发出咕噜咕噜的声音~好治愈!" << endl;
121 }
122 
123 // Dragon实现
124 Dragon::Dragon(const string& name, double price) 
125     : Toy(name, ToyType::DRAGON, price) {}
126 
127 void Dragon::specialFunction() {
128     if (!is_on) {
129         cout << name << " 未开启,无法使用特异功能!" << endl;
130         return;
131     }
132     if (battery_level < 20) {
133         cout << name << " 电量不足,无法使用特异功能!" << endl;
134         return;
135     }
136     battery_level -= 15;
137     breatheFire();
138 }
139 
140 void Dragon::breatheFire() {
141     cout << "" << name << " 喷出熊熊火焰!温度高达1000度!" << endl;
142 }
143 
144 // ToyFactory实现
145 ToyFactory::ToyFactory() {}
146 
147 ToyFactory::~ToyFactory() {
148     for (auto toy : toys) {
149         delete toy;
150     }
151 }
152 
153 void ToyFactory::addToy(Toy* toy) {
154     toys.push_back(toy);
155 }
156 
157 void ToyFactory::displayAllToys() const {
158     cout << "=== 玩具工厂库存 ===" << endl;
159     cout << "玩具总数: " << toys.size() << endl;
160     for (const auto& toy : toys) {
161         toy->displayInfo();
162     }
163     cout << "===================" << endl;
164 }
165 
166 void ToyFactory::demonstrateAllFunctions() const {
167     cout << "=== 所有玩具特异功能演示 ===" << endl;
168     for (const auto& toy : toys) {
169         cout << "\n演示 " << toy->getName() << " 的特异功能:" << endl;
170         toy->turnOn();  // 先开启玩具
171         toy->specialFunction();
172         toy->turnOff();  // 演示后关闭玩具
173     }
174     cout << "===========================" << endl;
175 }
176 
177 void ToyFactory::chargeAllToys(int amount) {
178     cout << "=== 为所有玩具充电 ===" << endl;
179     for (const auto& toy : toys) {
180         toy->charge(amount);
181     }
182     cout << "====================" << endl;
183 }
184 
185 // 工具函数实现
186 string toyTypeToString(ToyType type) {
187     switch (type) {
188         case ToyType::BEAR: return "泰迪熊";
189         case ToyType::RABBIT: return "兔子";
190         case ToyType::DOG: return "小狗";
191         case ToyType::CAT: return "小猫";
192         case ToyType::DRAGON: return "";
193         default: return "未知类型";
194     }
195 }
196 
197 Toy* createToy(ToyType type, const string& name, double price) {
198     switch (type) {
199         case ToyType::BEAR: return new TeddyBear(name, price);
200         case ToyType::RABBIT: return new Rabbit(name, price);
201         case ToyType::DOG: return new Dog(name, price);
202         case ToyType::CAT: return new Cat(name, price);
203         case ToyType::DRAGON: return new Dragon(name, price);
204         default: return nullptr;
205     }
206 }
  1 #pragma once
  2 
  3 #include <string>
  4 #include <memory>
  5 #include <vector>
  6 
  7 // 玩具类型枚举
  8 enum class ToyType {
  9     BEAR,        // 泰迪熊
 10     RABBIT,      // 兔子
 11     DOG,         // 小狗
 12     CAT,         // 小猫
 13     DRAGON       //
 14 };
 15 
 16 // 抽象基类:毛绒玩具
 17 class Toy {
 18 public:
 19     Toy(const std::string& name, ToyType type, double price, int battery = 100);
 20     virtual ~Toy() = default;
 21     
 22     // 公共接口
 23     virtual void specialFunction() = 0;  // 纯虚函数:特异功能
 24     virtual void displayInfo() const;     // 显示基本信息
 25     void turnOn();
 26     void turnOff();
 27     void charge(int amount);
 28     bool isOn() const { return is_on; }
 29     int getBattery() const { return battery_level; }
 30     std::string getName() const { return name; }
 31     ToyType getType() const { return type; }
 32     double getPrice() const { return price; }
 33 
 34 protected:
 35     std::string name;
 36     ToyType type;
 37     double price;
 38     int battery_level;
 39     bool is_on;
 40 };
 41 
 42 // 具体玩具类:泰迪熊
 43 class TeddyBear : public Toy {
 44 public:
 45     TeddyBear(const std::string& name, double price);
 46     void specialFunction() override;
 47     void hug();  // 特有功能:拥抱
 48 };
 49 
 50 // 具体玩具类:兔子
 51 class Rabbit : public Toy {
 52 public:
 53     Rabbit(const std::string& name, double price);
 54     void specialFunction() override;
 55     void jump();  // 特有功能:跳跃
 56 };
 57 
 58 // 具体玩具类:小狗
 59 class Dog : public Toy {
 60 public:
 61     Dog(const std::string& name, double price);
 62     void specialFunction() override;
 63     void bark();  // 特有功能:吠叫
 64 };
 65 
 66 // 具体玩具类:小猫
 67 class Cat : public Toy {
 68 public:
 69     Cat(const std::string& name, double price);
 70     void specialFunction() override;
 71     void purr();  // 特有功能:呼噜声
 72 };
 73 
 74 // 具体玩具类:龙
 75 class Dragon : public Toy {
 76 public:
 77     Dragon(const std::string& name, double price);
 78     void specialFunction() override;
 79     void breatheFire();  // 特有功能:喷火
 80 };
 81 
 82 // 玩具工厂类
 83 class ToyFactory {
 84 public:
 85     ToyFactory();
 86     ~ToyFactory();
 87     
 88     void addToy(Toy* toy);
 89     void displayAllToys() const;
 90     void demonstrateAllFunctions() const;
 91     void chargeAllToys(int amount);
 92     int getToyCount() const { return toys.size(); }
 93 
 94 private:
 95     std::vector<Toy*> toys;
 96 };
 97 
 98 // 工具函数
 99 std::string toyTypeToString(ToyType type);
100 Toy* createToy(ToyType type, const std::string& name, double price);
 1 #include <iostream>
 2 #include "Toy.hpp"
 3 
 4 using namespace std;
 5 
 6 void test() {
 7     cout << "=== 毛绒玩具系统测试 ===" << endl;
 8     
 9     // 创建玩具工厂
10     ToyFactory factory;
11     
12     // 添加各种玩具
13     factory.addToy(createToy(ToyType::BEAR, "泰迪", 199.9));
14     factory.addToy(createToy(ToyType::RABBIT, "小白兔", 159.9));
15     factory.addToy(createToy(ToyType::DOG, "旺财", 179.9));
16     factory.addToy(createToy(ToyType::CAT, "咪咪", 169.9));
17     factory.addToy(createToy(ToyType::DRAGON, "小火龙", 299.9));
18     
19     // 显示所有玩具信息
20     factory.displayAllToys();
21     
22     // 为所有玩具充电
23     factory.chargeAllToys(30);
24     
25     // 演示所有特异功能
26     factory.demonstrateAllFunctions();
27     
28     // 再次显示信息查看电量消耗
29     cout << "\n=== 演示后的玩具状态 ===" << endl;
30     factory.displayAllToys();
31     
32     cout << "=== 测试完成 ===" << endl;
33 }
34 
35 int main() {
36     test();
37     return 0;
38 }

1.问题场景描述:在现代玩具制造和零售行业中,毛绒玩具种类日益丰富,每种玩具都具有独特的"特异功能"(如泰迪熊的拥抱、兔子的跳跃、小狗的吠叫等)。传统玩具管理系统面临以下核心问题:

接口不统一:不同玩具功能差异大,缺乏统一管理接口   扩展性差:新增玩具类型需要大量修改现有代码结构   维护困难:功能分散,缺乏统一的生命周期管理   资源管理复杂:动态创建的玩具对象内存管理困难

技术挑战:如何实现"一个接口尝试所有玩具特异功能"的设计目标   如何平衡代码的可扩展性和维护性   如何确保资源的安全管理和释放

2.继承关系

Toy(抽象基类)
├── TeddyBear(泰迪熊)
├── Rabbit(兔子)
├── Dog(小狗)
├── Cat(小猫)
└── Dragon(龙)

代码:

class Toy { /* 抽象基类 */ };
class TeddyBear : public Toy { /* 具体实现 */ };
class Rabbit : public Toy { /* 具体实现 */ };

设计理由:所有玩具共享名称、价格、电量等通用属性,新增玩具类型只需继承Toy基类,无需修改现有代码

3.组合关系

ToyFactory(玩具工厂)
└── std::vector<Toy*> toys(玩具集合)

代码:

class ToyFactory {
private:
std::vector<Toy*> toys; // 组合关系
public:
void addToy(Toy* toy);
void demonstrateAllFunctions();
};

设计理由:工厂负责创建和销毁所有玩具对象,通过容器集中管理所有玩具,简化操作

 

posted @ 2025-12-02 17:23  Zhades  阅读(7)  评论(0)    收藏  举报