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 }
#运行结果

#问题回答
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 }
#运行结果

#问题回答
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 }
#运行结果

#问题回答
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();
};
设计理由:工厂负责创建和销毁所有玩具对象,通过容器集中管理所有玩具,简化操作
浙公网安备 33010602011771号