实验4 组合与继承
实验任务1
1 #include <iostream> 2 #include <algorithm> 3 #include <iomanip> 4 #include <numeric> 5 #include <stdexcept> 6 7 class GradeCalc { 8 public: 9 GradeCalc(const std::string &cname) : 10 course_name(cname), 11 is_dirty(true) { 12 counts.fill(0); 13 rates.fill(0.0); 14 } 15 16 void input(int n) { 17 if (n <= 0) { 18 throw std::invalid_argument("Number of grades must be positive"); 19 } 20 21 grades.reserve(grades.size() + n); 22 std::cout << "Please enter " << n << " grades (0-100):" << std::endl; 23 24 for (int i = 0; i < n; ++i) { 25 int grade; 26 std::cin >> grade; 27 28 // 输入验证 29 if (grade < 0 || grade > 100) { 30 throw std::out_of_range("Grade must be between 0 and 100"); 31 } 32 33 grades.push_back(grade); 34 } 35 36 is_dirty = true; // 数据已更新,需要重新计算 37 } 38 39 void output() const { 40 if (grades.empty()) { 41 std::cout << "No grades recorded." << std::endl; 42 return; 43 } 44 45 std::cout << "Grades for course: " << course_name << std::endl; 46 std::cout << "Grades: "; 47 48 for (size_t i = 0; i < grades.size(); ++i) { 49 std::cout << grades[i]; 50 if (i != grades.size() - 1) { 51 std::cout << ", "; 52 } 53 } 54 std::cout << std::endl; 55 } 56 57 void sort(bool ascending = false) { 58 if (ascending) { 59 std::sort(grades.begin(), grades.end()); 60 } else { 61 std::sort(grades.begin(), grades.end(), std::greater<int>()); 62 } 63 } 64 65 int min() const { 66 if (grades.empty()) { 67 return -1; 68 } 69 return *std::min_element(grades.begin(), grades.end()); 70 } 71 72 int max() const { 73 if (grades.empty()) { 74 return -1; 75 } 76 return *std::max_element(grades.begin(), grades.end()); 77 } 78 79 double average() const { 80 if (grades.empty()) { 81 return 0.0; 82 } 83 84 double sum = std::accumulate(grades.begin(), grades.end(), 0.0); 85 return sum / grades.size(); 86 } 87 88 void info() { 89 // 如果数据有变更,重新计算统计信息 90 if (is_dirty) { 91 compute(); 92 is_dirty = false; 93 } 94 95 std::cout << "==========================================" << std::endl; 96 std::cout << "Course: " << course_name << std::endl; 97 std::cout << "==========================================" << std::endl; 98 std::cout << "Total number of grades: " << grades.size() << std::endl; 99 std::cout << "Minimum grade: " << (grades.empty() ? "N/A" : std::to_string(min())) << std::endl; 100 std::cout << "Maximum grade: " << (grades.empty() ? "N/A" : std::to_string(max())) << std::endl; 101 std::cout << "Average grade: " << std::fixed << std::setprecision(2) << average() << std::endl; 102 std::cout << std::endl; 103 104 // 输出分数段统计 105 if (!grades.empty()) { 106 std::cout << "Grade Distribution:" << std::endl; 107 std::cout << "-------------------" << std::endl; 108 109 std::array<std::string, 5> ranges = { 110 "[0, 60)", "[60, 70)", "[70, 80)", "[80, 90)", "[90, 100]" 111 }; 112 113 for (int i = 0; i < 5; ++i) { 114 std::cout << std::setw(10) << ranges[i] << ": " 115 << std::setw(3) << counts[i] << " students (" 116 << std::fixed << std::setprecision(1) << rates[i] * 100 117 << "%)" << std::endl; 118 } 119 } 120 std::cout << "==========================================" << std::endl; 121 } 122 123 private: 124 void compute() { 125 // 重置统计数据 126 counts.fill(0); 127 rates.fill(0.0); 128 129 if (grades.empty()) { 130 return; 131 } 132 133 // 统计各分数段人数 134 for (int grade : grades) { 135 if (grade < 60) { 136 counts[0]++; 137 } else if (grade < 70) { 138 counts[1]++; 139 } else if (grade < 80) { 140 counts[2]++; 141 } else if (grade < 90) { 142 counts[3]++; 143 } else { 144 counts[4]++; 145 } 146 } 147 148 // 计算各分数段占比 149 double total = grades.size(); 150 for (int i = 0; i < 5; ++i) { 151 rates[i] = counts[i] / total; 152 } 153 } 154 155 private: 156 std::string course_name; // 课程名 157 std::vector<int> grades; // 课程成绩 158 std::array<int, 5> counts; // 保存各分数段人数([0, 60), [60, 70), [70, 80), [80, 90), [90, 100] 159 std::array<double, 5> rates; // 保存各分数段人数占比 160 bool is_dirty; // 脏标记,记录是否成绩信息有变更 161 };

std::string course_name; // 课程名,用于存储课程名称字符串
std::vector<int> grades; // 课程成绩,用于动态存储和管理所有成绩
std::array<int, 5> counts; // 保存各分数段人数,用于统计不同分数区间的人数
std::array<double, 5> rates; // 保存各分数段人数占比,用于计算各分数段的比例
不合法
GradeCalc c("OOP");
c.inupt(5); // 不合法:拼写错误,应该是input()而不是inupt()
c.push_back(97); // 不合法:push_back()是私有成员
compute()只会被调用1次,避免重复计算
修改成绩后,原有的统计信息已失效,需要将is_dirty设为true,这样下次调用info()时会自动重新计算
void info() {
if (is_dirty) {
compute();
is_dirty = false;
}
if (!grades.empty()) {
std::vector<int> temp_grades = grades;
std::sort(temp_grades.begin(), temp_grades.end());
double median;
size_t n = temp_grades.size();
if (n % 2 == 0) {
median = (temp_grades[n/2 - 1] + temp_grades[n/2]) / 2.0;
} else {
median = temp_grades[n/2];
}
std::cout << "Median grade: " << std::fixed << std::setprecision(2)
<< median << std::endl;
}
}
累加错误:新统计会在旧的counts/rates基础上累加,而不是重新计算
数据污染:部分统计可能包含上一轮的数据残留
结果不一致:统计结果与实际情况不符
去掉reserve()会导致vector在增长过程中多次重新分配内存,增加运行时间开销
实验任务2
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 // 构造函数 - 已完整 12 GradeCalc::GradeCalc(const std::string &cname): course_name{cname}, is_dirty{true}{ 13 counts.fill(0); 14 rates.fill(0); 15 } 16 17 // input() - 已完整 18 void GradeCalc::input(int n) { 19 if(n < 0) { 20 std::cerr << "无效输入! 人数不能为负数\n"; 21 return; 22 } 23 24 this->reserve(n); 25 26 int grade; 27 28 for(int i = 0; i < n;) { 29 std::cin >> grade; 30 if(grade < 0 || grade > 100) { 31 std::cerr << "无效输入! 分数须在[0,100]\n"; 32 continue; 33 } 34 35 this->push_back(grade); 36 ++i; 37 } 38 39 is_dirty = true; 40 } 41 42 // output() - 已完整 43 void GradeCalc::output() const { 44 for(auto grade: *this) 45 std::cout << grade << ' '; 46 std::cout << std::endl; 47 } 48 49 // sort() - 已完整 50 void GradeCalc::sort(bool ascending) { 51 if(ascending) 52 std::sort(this->begin(), this->end()); 53 else 54 std::sort(this->begin(), this->end(), std::greater<int>()); 55 } 56 57 // min() - 已完整 58 int GradeCalc::min() const { 59 if(this->empty()) 60 return -1; 61 62 return *std::min_element(this->begin(), this->end()); 63 } 64 65 // max() - 已完整 66 int GradeCalc::max() const { 67 if(this->empty()) 68 return -1; 69 70 return *std::max_element(this->begin(), this->end()); 71 } 72 73 // average() - 已完整 74 double GradeCalc::average() const { 75 if(this->empty()) 76 return 0.0; 77 78 double avg = std::accumulate(this->begin(), this->end(), 0.0) / this->size(); 79 return avg; 80 } 81 82 // info() - 已完整 83 void GradeCalc::info() { 84 if(is_dirty) 85 compute(); 86 87 std::cout << "课程名称:\t" << course_name << std::endl; 88 std::cout << "平均分:\t" << std::fixed << std::setprecision(2) << average() << std::endl; 89 std::cout << "最高分:\t" << max() << std::endl; 90 std::cout << "最低分:\t" << min() << std::endl; 91 92 const std::array<std::string, 5> grade_range{"[0, 60) ", 93 "[60, 70)", 94 "[70, 80)", 95 "[80, 90)", 96 "[90, 100]"}; 97 98 for(int i = static_cast<int>(grade_range.size())-1; i >= 0; --i) 99 std::cout << grade_range[i] << "\t: " << counts[i] << "人\t" 100 << std::fixed << std::setprecision(2) << rates[i]*100 << "%\n"; 101 } 102 103 // compute() - 已完整 104 void GradeCalc::compute() { 105 if(this->empty()) 106 return; 107 108 counts.fill(0); 109 rates.fill(0); 110 111 // 统计各分数段人数 112 for(int grade: *this) { 113 if(grade < 60) 114 ++counts[0]; // [0, 60) 115 else if (grade < 70) 116 ++counts[1]; // [60, 70) 117 else if (grade < 80) 118 ++counts[2]; // [70, 80) 119 else if (grade < 90) 120 ++counts[3]; // [80, 90) 121 else 122 ++counts[4]; // [90, 100] 123 } 124 125 // 统计各分数段比例 126 for(size_t i = 0; i < rates.size(); ++i) 127 rates[i] = counts[i] * 1.0 / this->size(); 128 129 is_dirty = false; 130 } 131 132 // 以下是可选的辅助函数,可以根据需要添加: 133 134 // 获取课程名称 135 std::string GradeCalc::getCourseName() const { 136 return course_name; 137 } 138 139 // 设置课程名称 140 void GradeCalc::setCourseName(const std::string& name) { 141 course_name = name; 142 } 143 144 // 获取分数段统计 145 std::array<int, 5> GradeCalc::getGradeCounts() const { 146 return counts; 147 } 148 149 // 获取分数段比例 150 std::array<double, 5> GradeCalc::getGradeRates() const { 151 return rates; 152 } 153 154 // 清除所有成绩 155 void GradeCalc::clearGrades() { 156 this->clear(); 157 counts.fill(0); 158 rates.fill(0); 159 is_dirty = false; 160 } 161 162 // 获取成绩数量 163 size_t GradeCalc::getGradeCount() const { 164 return this->size(); 165 }

class GradeCalc : public std::vector<int> { // 这里体现了公有继承关系
当前设计下 c.push_back(97) 是合法的,但可能破坏数据一致性。更好的设计是使用组合而非继承
组合方案更合适,因为成绩计算器使用vector存储成绩(has-a关系),而不是它本身是一个vector(is-a关系)
实验任务3
1 #ifndef GRAPH_HPP 2 #define GRAPH_HPP 3 4 #include <vector> 5 #include <string> 6 7 // 图形类型枚举 8 enum class GraphType { 9 circle, 10 triangle, 11 rectangle 12 }; 13 14 // 抽象基类 Graph 15 class Graph { 16 public: 17 virtual ~Graph() = default; // 虚析构函数 18 virtual void draw() = 0; // 纯虚函数 19 }; 20 21 // 具体图形类 22 class Circle : public Graph { 23 public: 24 void draw() override; 25 }; 26 27 class Triangle : public Graph { 28 public: 29 void draw() override; 30 }; 31 32 class Rectangle : public Graph { 33 public: 34 void draw() override; 35 }; 36 37 // Canvas 画布类 38 class Canvas { 39 public: 40 void add(const std::string& type); // 添加图形 41 void paint() const; // 绘制所有图形 42 ~Canvas(); // 析构函数 43 44 private: 45 std::vector<Graph*> graphs; // 存储图形指针 46 }; 47 48 // 工具函数声明 49 GraphType str_to_GraphType(const std::string& s); 50 Graph* make_graph(const std::string& type); 51 52 #endif // GRAPH_HPP

std::vector<Graph*> graphs; // 存储图形对象的指针集合,功能:Canvas 类通过该 vector 管理一组图形对象的指针,实现图形对象的聚合管理
class Circle : public Graph { ... };
class Triangle : public Graph { ... };
class Rectangle : public Graph { ... };
运行结果:Canvas::paint() 中的 g->draw() 将无法实现多态,会调用基类 Graph 的 draw() 方法(如果存在),或者编译错误(如果是纯虚函数)
对象切片(Object Slicing):只能存储 Graph 基类对象,丢失派生类的特有数据和方法
多态失效:无法存储 Circle/Triangle/Rectangle 对象
编译错误:Graph 是抽象类(包含纯虚函数),无法实例化,vector 元素分配会失败
类型不匹配:无法将派生类对象赋值给基类对象
当通过基类指针删除派生类对象时,只会调用基类的析构函数,导致派生类对象的部分资源泄漏
// 在枚举中添加
enum class GraphType {
circle,
triangle,
rectangle,
star // 新增
};
class Star : public Graph {
public:
void draw() override;
};
释放位置:在 Canvas::~Canvas() 析构函数中释放
利:
性能好:没有智能指针的开销
控制灵活:可以精确控制内存分配和释放时机
兼容性好:与 C 语言和其他库接口兼容
弊:
容易内存泄漏:忘记 delete 或异常发生时可能泄漏
悬垂指针:可能访问已释放的内存
双重释放:同一指针被 delete 两次
所有权不明确:不清楚谁负责释放内存
不符合 RAII:需要手动管理资源生命周期
实验任务4
1 #ifndef TOY_HPP 2 #define TOY_HPP 3 4 #include <string> 5 #include <memory> 6 #include <vector> 7 #include <iostream> 8 9 // 玩具类型枚举 10 enum class ToyType { 11 BEAR, // 毛绒熊 12 BUNNY, // 兔子 13 ELEPHANT, // 大象 14 UNICORN, // 独角兽 15 ROBOT // 机器人 16 }; 17 18 // 抽象基类:玩具 19 class Toy { 20 public: 21 Toy(const std::string& name, ToyType type, float price, int ageLimit); 22 virtual ~Toy() = default; 23 24 // 基本信息获取 25 std::string getName() const; 26 ToyType getType() const; 27 float getPrice() const; 28 int getAgeLimit() const; 29 30 // 玩具特异功能(虚函数,子类可以重写) 31 virtual void play() const = 0; // 玩耍方式 32 virtual void makeSound() const; // 发出声音 33 virtual void showSpecialFeature() const = 0; // 展示特异功能 34 35 // 其他功能 36 virtual void displayInfo() const; // 显示玩具信息 37 38 protected: 39 std::string name; 40 ToyType type; 41 float price; 42 int ageLimit; // 适合年龄下限 43 }; 44 45 // 具体玩具类:毛绒熊 46 class StuffedBear : public Toy { 47 public: 48 StuffedBear(const std::string& name, float price, int ageLimit, 49 bool hasHeartbeat = false, bool canHug = true); 50 51 void play() const override; 52 void makeSound() const override; 53 void showSpecialFeature() const override; 54 void displayInfo() const override; 55 56 private: 57 bool hasHeartbeat; // 有心跳功能 58 bool canHug; // 可拥抱 59 }; 60 61 // 具体玩具类:兔子 62 class Bunny : public Toy { 63 public: 64 Bunny(const std::string& name, float price, int ageLimit, 65 bool canJump = false, std::string furColor = "white"); 66 67 void play() const override; 68 void makeSound() const override; 69 void showSpecialFeature() const override; 70 void displayInfo() const override; 71 72 private: 73 bool canJump; 74 std::string furColor; 75 }; 76 77 // 具体玩具类:独角兽 78 class Unicorn : public Toy { 79 public: 80 Unicorn(const std::string& name, float price, int ageLimit, 81 bool canGlow = true, bool hasRainbowTail = true); 82 83 void play() const override; 84 void makeSound() const override; 85 void showSpecialFeature() const override; 86 void displayInfo() const override; 87 88 private: 89 bool canGlow; // 可以发光 90 bool hasRainbowTail; // 有彩虹尾巴 91 }; 92 93 // 具体玩具类:机器人玩具 94 class RobotToy : public Toy { 95 public: 96 RobotToy(const std::string& name, float price, int ageLimit, 97 bool canWalk = true, bool canTalk = true, int batteryLife = 5); 98 99 void play() const override; 100 void makeSound() const override; 101 void showSpecialFeature() const override; 102 void displayInfo() const override; 103 104 void recharge(); // 特有功能:充电 105 106 private: 107 bool canWalk; 108 bool canTalk; 109 int batteryLife; // 电池续航时间(小时) 110 }; 111 112 // 玩具工厂类 113 class ToyFactory { 114 public: 115 ToyFactory() = default; 116 117 // 添加玩具 118 void addToy(std::shared_ptr<Toy> toy); 119 120 // 批量生产玩具 121 void produceStandardToys(); 122 123 // 显示所有玩具信息 124 void displayAllToys() const; 125 126 // 按类型显示玩具 127 void displayToysByType(ToyType type) const; 128 129 // 查找玩具 130 std::shared_ptr<Toy> findToyByName(const std::string& name) const; 131 132 // 演示所有玩具的特异功能 133 void demonstrateAllFeatures() const; 134 135 // 统计信息 136 int getTotalToys() const; 137 float getTotalValue() const; 138 139 private: 140 std::vector<std::shared_ptr<Toy>> toys; 141 142 // 辅助函数:类型转字符串 143 std::string typeToString(ToyType type) const; 144 }; 145 146 #endif // TOY_HPP
1 #include "Toy.hpp" 2 #include <iomanip> 3 #include <algorithm> 4 5 // ============ Toy 基类实现 ============ 6 Toy::Toy(const std::string& name, ToyType type, float price, int ageLimit) 7 : name(name), type(type), price(price), ageLimit(ageLimit) {} 8 9 std::string Toy::getName() const { return name; } 10 ToyType Toy::getType() const { return type; } 11 float Toy::getPrice() const { return price; } 12 int Toy::getAgeLimit() const { return ageLimit; } 13 14 void Toy::makeSound() const { 15 std::cout << name << " makes a generic toy sound!" << std::endl; 16 } 17 18 void Toy::displayInfo() const { 19 std::cout << "Name: " << name 20 << ", Type: " << static_cast<int>(type) 21 << ", Price: $" << std::fixed << std::setprecision(2) << price 22 << ", Age Limit: " << ageLimit << "+" << std::endl; 23 } 24 25 // ============ StuffedBear 实现 ============ 26 StuffedBear::StuffedBear(const std::string& name, float price, int ageLimit, 27 bool hasHeartbeat, bool canHug) 28 : Toy(name, ToyType::BEAR, price, ageLimit), 29 hasHeartbeat(hasHeartbeat), canHug(canHug) {} 30 31 void StuffedBear::play() const { 32 std::cout << name << " is being hugged and cuddled!" << std::endl; 33 } 34 35 void StuffedBear::makeSound() const { 36 std::cout << name << " says: Growl! I'm a fluffy bear!" << std::endl; 37 } 38 39 void StuffedBear::showSpecialFeature() const { 40 std::cout << name << " special features:" << std::endl; 41 if (hasHeartbeat) { 42 std::cout << " - Has a realistic heartbeat" << std::endl; 43 } 44 if (canHug) { 45 std::cout << " - Can give warm hugs" << std::endl; 46 } 47 } 48 49 void StuffedBear::displayInfo() const { 50 Toy::displayInfo(); 51 showSpecialFeature(); 52 } 53 54 // ============ Bunny 实现 ============ 55 Bunny::Bunny(const std::string& name, float price, int ageLimit, 56 bool canJump, std::string furColor) 57 : Toy(name, ToyType::BUNNY, price, ageLimit), 58 canJump(canJump), furColor(furColor) {} 59 60 void Bunny::play() const { 61 std::cout << name << " is hopping around happily!" << std::endl; 62 } 63 64 void Bunny::makeSound() const { 65 std::cout << name << " says: Sniff sniff! What's for dinner?" << std::endl; 66 } 67 68 void Bunny::showSpecialFeature() const { 69 std::cout << name << " special features:" << std::endl; 70 std::cout << " - Fur color: " << furColor << std::endl; 71 if (canJump) { 72 std::cout << " - Can jump when squeezed" << std::endl; 73 } 74 } 75 76 void Bunny::displayInfo() const { 77 Toy::displayInfo(); 78 showSpecialFeature(); 79 } 80 81 // ============ Unicorn 实现 ============ 82 Unicorn::Unicorn(const std::string& name, float price, int ageLimit, 83 bool canGlow, bool hasRainbowTail) 84 : Toy(name, ToyType::UNICORN, price, ageLimit), 85 canGlow(canGlow), hasRainbowTail(hasRainbowTail) {} 86 87 void Unicorn::play() const { 88 std::cout << name << " is spreading magic and joy!" << std::endl; 89 } 90 91 void Unicorn::makeSound() const { 92 std::cout << name << " says: Neigh! I bring magic!" << std::endl; 93 } 94 95 void Unicorn::showSpecialFeature() const { 96 std::cout << name << " special features:" << std::endl; 97 if (canGlow) { 98 std::cout << " - Horn glows in the dark" << std::endl; 99 } 100 if (hasRainbowTail) { 101 std::cout << " - Has a rainbow-colored tail" << std::endl; 102 } 103 } 104 105 void Unicorn::displayInfo() const { 106 Toy::displayInfo(); 107 showSpecialFeature(); 108 } 109 110 // ============ RobotToy 实现 ============ 111 RobotToy::RobotToy(const std::string& name, float price, int ageLimit, 112 bool canWalk, bool canTalk, int batteryLife) 113 : Toy(name, ToyType::ROBOT, price, ageLimit), 114 canWalk(canWalk), canTalk(canTalk), batteryLife(batteryLife) {} 115 116 void RobotToy::play() const { 117 std::cout << name << " is moving around and interacting!" << std::endl; 118 } 119 120 void RobotToy::makeSound() const { 121 std::cout << name << " says: Beep boop! I'm a robot!" << std::endl; 122 } 123 124 void RobotToy::showSpecialFeature() const { 125 std::cout << name << " special features:" << std::endl; 126 if (canWalk) { 127 std::cout << " - Can walk autonomously" << std::endl; 128 } 129 if (canTalk) { 130 std::cout << " - Can speak multiple phrases" << std::endl; 131 } 132 std::cout << " - Battery life: " << batteryLife << " hours" << std::endl; 133 } 134 135 void RobotToy::displayInfo() const { 136 Toy::displayInfo(); 137 showSpecialFeature(); 138 } 139 140 void RobotToy::recharge() { 141 batteryLife = 10; 142 std::cout << name << " has been recharged to full battery!" << std::endl; 143 } 144 145 // ============ ToyFactory 实现 ============ 146 void ToyFactory::addToy(std::shared_ptr<Toy> toy) { 147 toys.push_back(toy); 148 } 149 150 void ToyFactory::produceStandardToys() { 151 // 生产一些标准玩具 152 toys.push_back(std::make_shared<StuffedBear>("Teddy", 29.99, 3, true, true)); 153 toys.push_back(std::make_shared<Bunny>("Fluffy", 19.99, 2, true, "white")); 154 toys.push_back(std::make_shared<Unicorn>("Sparkle", 39.99, 4, true, true)); 155 toys.push_back(std::make_shared<RobotToy>("RoboBuddy", 49.99, 6, true, true, 8)); 156 toys.push_back(std::make_shared<StuffedBear>("Brownie", 24.99, 3, false, true)); 157 } 158 159 void ToyFactory::displayAllToys() const { 160 std::cout << "\n=== All Toys in Factory ===" << std::endl; 161 for (const auto& toy : toys) { 162 toy->displayInfo(); 163 std::cout << std::endl; 164 } 165 } 166 167 void ToyFactory::displayToysByType(ToyType type) const { 168 std::cout << "\n=== Toys of Type: " << typeToString(type) << " ===" << std::endl; 169 for (const auto& toy : toys) { 170 if (toy->getType() == type) { 171 toy->displayInfo(); 172 std::cout << std::endl; 173 } 174 } 175 } 176 177 std::shared_ptr<Toy> ToyFactory::findToyByName(const std::string& name) const { 178 for (const auto& toy : toys) { 179 if (toy->getName() == name) { 180 return toy; 181 } 182 } 183 return nullptr; 184 } 185 186 void ToyFactory::demonstrateAllFeatures() const { 187 std::cout << "\n=== Demonstrating All Toy Features ===" << std::endl; 188 for (const auto& toy : toys) { 189 std::cout << "\n--- " << toy->getName() << " ---" << std::endl; 190 toy->play(); 191 toy->makeSound(); 192 toy->showSpecialFeature(); 193 } 194 } 195 196 int ToyFactory::getTotalToys() const { 197 return static_cast<int>(toys.size()); 198 } 199 200 float ToyFactory::getTotalValue() const { 201 float total = 0; 202 for (const auto& toy : toys) { 203 total += toy->getPrice(); 204 } 205 return total; 206 } 207 208 std::string ToyFactory::typeToString(ToyType type) const { 209 switch (type) { 210 case ToyType::BEAR: return "Stuffed Bear"; 211 case ToyType::BUNNY: return "Bunny"; 212 case ToyType::UNICORN: return "Unicorn"; 213 case ToyType::ROBOT: return "Robot Toy"; 214 default: return "Unknown"; 215 } 216 }
1 #include "Toy.hpp" 2 #include <iostream> 3 #include <memory> 4 5 void testToySystem() { 6 std::cout << "========== Toy Factory System Test ==========\n" << std::endl; 7 8 // 创建玩具工厂 9 ToyFactory factory; 10 11 // 1. 生产标准玩具 12 std::cout << "1. Producing standard toys..." << std::endl; 13 factory.produceStandardToys(); 14 15 // 2. 添加自定义玩具 16 std::cout << "\n2. Adding custom toys..." << std::endl; 17 factory.addToy(std::make_shared<Bunny>("Cotton", 22.50, 2, false, "brown")); 18 factory.addToy(std::make_shared<RobotToy>("TechBot", 59.99, 8, true, true, 12)); 19 20 // 3. 显示所有玩具信息 21 factory.displayAllToys(); 22 23 // 4. 按类型显示玩具 24 std::cout << "\n4. Showing bears only:" << std::endl; 25 factory.displayToysByType(ToyType::BEAR); 26 27 // 5. 演示所有玩具的特异功能 28 factory.demonstrateAllFeatures(); 29 30 // 6. 查找特定玩具 31 std::cout << "\n6. Searching for specific toy..." << std::endl; 32 auto foundToy = factory.findToyByName("Sparkle"); 33 if (foundToy) { 34 std::cout << "Found toy: "; 35 foundToy->displayInfo(); 36 } 37 38 // 7. 测试多态性 39 std::cout << "\n7. Testing polymorphism..." << std::endl; 40 std::vector<std::shared_ptr<Toy>> toyCollection; 41 42 // 创建不同类型的玩具 43 toyCollection.push_back(std::make_shared<StuffedBear>("Grizzly", 34.99, 4, true, true)); 44 toyCollection.push_back(std::make_shared<Unicorn>("Magic", 44.99, 5, true, false)); 45 toyCollection.push_back(std::make_shared<RobotToy>("Android", 69.99, 10, true, false, 24)); 46 47 // 通过基类指针调用不同方法(多态) 48 std::cout << "\nDemonstrating polymorphism with a mixed collection:" << std::endl; 49 for (const auto& toy : toyCollection) { 50 std::cout << "\n--- " << toy->getName() << " ---" << std::endl; 51 toy->play(); // 每个玩具有自己的玩耍方式 52 toy->makeSound(); // 每个玩具有自己的声音 53 toy->showSpecialFeature(); // 每个玩具展示自己的特异功能 54 } 55 56 // 8. 统计信息 57 std::cout << "\n8. Factory Statistics:" << std::endl; 58 std::cout << "Total toys in factory: " << factory.getTotalToys() << std::endl; 59 std::cout << "Total value of toys: $" << std::fixed << std::setprecision(2) 60 << factory.getTotalValue() << std::endl; 61 62 // 9. 测试动态类型转换 63 std::cout << "\n9. Testing dynamic casting..." << std::endl; 64 auto robot = std::dynamic_pointer_cast<RobotToy>(factory.findToyByName("TechBot")); 65 if (robot) { 66 std::cout << "Found a robot toy, testing recharge function:" << std::endl; 67 robot->recharge(); 68 } 69 70 std::cout << "\n========== Test Complete ==========" << std::endl; 71 } 72 73 void testEdgeCases() { 74 std::cout << "\n\n========== Testing Edge Cases ==========\n" << std::endl; 75 76 ToyFactory smallFactory; 77 78 // 测试空工厂 79 std::cout << "1. Empty factory test:" << std::endl; 80 std::cout << "Total toys: " << smallFactory.getTotalToys() << std::endl; 81 smallFactory.displayAllToys(); 82 83 // 测试查找不存在的玩具 84 std::cout << "\n2. Searching for non-existent toy:" << std::endl; 85 auto toy = smallFactory.findToyByName("Nonexistent"); 86 if (!toy) { 87 std::cout << "Toy not found (as expected)" << std::endl; 88 } 89 } 90 91 int main() { 92 std::cout << "DEMO 4: Toy Factory System" << std::endl; 93 std::cout << "===========================\n" << std::endl; 94 95 try { 96 // 运行主要测试 97 testToySystem(); 98 99 // 运行边界情况测试 100 testEdgeCases(); 101 102 std::cout << "\nAll tests passed successfully!" << std::endl; 103 104 } catch (const std::exception& e) { 105 std::cerr << "Error: " << e.what() << std::endl; 106 return 1; 107 } 108 109 return 0; 110 }

浙公网安备 33010602011771号