实验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 };
View Code

螢幕擷取畫面 2025-12-02 185441

 

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 }
View Code

螢幕擷取畫面 2025-12-02 190920

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
View Code

螢幕擷取畫面 2025-12-02 192548

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
View Code
  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 }
View Code
  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 }
View Code

 

posted @ 2025-12-02 19:37  ToffeeMa  阅读(2)  评论(0)    收藏  举报