C++课设:智能优惠快餐点餐系统

名人说:路漫漫其修远兮,吾将上下而求索。------ 屈原《离骚》
创作者:Code_流苏(CSDN) (一个喜欢古诗词和编程的Coder😊)
专栏介绍《编程项目实战》

目录

本文将从零开始构建一个功能完整的C++快餐点餐系统,深入学习面向对象编程 的精髓。通过实际项目开发,掌握类设计封装继承等核心概念,打造一个支持智能点餐、自动优惠、订单管理的实用系统。

一、项目介绍与亮点功能

1. 项目背景

在快餐行业数字化转型的大潮中,点餐系统已成为提升用户体验和运营效率的关键工具。我们将使用C++面向对象编程 思想,构建一个功能丰富的快餐点餐系统,让初学者在实战中深入理解面向对象设计模式

2.完整代码

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <ctime>
#include <sstream>

using namespace std;

// 菜品类
class MenuItem {
public:
    int id;
    string name;
    double price;
    string category;
    
    MenuItem(int _id, string _name, double _price, string _category) 
        : id(_id), name(_name), price(_price), category(_category) {}
};

// 订单项类
class OrderItem {
public:
    MenuItem item;
    int quantity;
    double subtotal;
    
    OrderItem(MenuItem _item, int _quantity) 
        : item(_item), quantity(_quantity) {
        subtotal = item.price * quantity;
    }
};

// 订单类
class Order {
public:
    string orderNumber;
    vector<OrderItem> items;
    double totalAmount;
    double discount;
    double finalAmount;
    string orderTime;
    
    Order() {
        generateOrderNumber();
        generateOrderTime();
        totalAmount = 0.0;
        discount = 0.0;
        finalAmount = 0.0;
    }
    
    void addItem(MenuItem item, int quantity) {
        // 检查是否已存在该商品,如果存在则增加数量
        for(int i = 0; i < items.size(); i++) {
            if(items[i].item.id == item.id) {
                items[i].quantity += quantity;
                items[i].subtotal = items[i].item.price * items[i].quantity;
                calculateTotal();
                return;
            }
        }
        // 如果不存在,添加新的订单项
        items.push_back(OrderItem(item, quantity));
        calculateTotal();
    }
    
    void calculateTotal() {
        totalAmount = 0.0;
        for(int i = 0; i < items.size(); i++) {
            totalAmount += items[i].subtotal;
        }
        
        // 计算优惠
        calculateDiscount();
        finalAmount = totalAmount - discount;
    }
    
    void calculateDiscount() {
        discount = 0.0;
        
        // 满额优惠:满100减10,满200减25,满300减40
        if(totalAmount >= 300) {
            discount = 40.0;
        } else if(totalAmount >= 200) {
            discount = 25.0;
        } else if(totalAmount >= 100) {
            discount = 10.0;
        }
        
        // 数量优惠:单品数量>=5打9折
        for(int i = 0; i < items.size(); i++) {
            if(items[i].quantity >= 5) {
                double itemDiscount = items[i].subtotal * 0.1;
                if(itemDiscount > discount) {
                    discount = itemDiscount;
                }
            }
        }
    }
    
private:
    void generateOrderNumber() {
        time_t now = time(0);
        stringstream ss;
        ss << "ORD" << now % 100000;
        orderNumber = ss.str();
    }
    
    void generateOrderTime() {
        time_t now = time(0);
        char* timeStr = ctime(&now);
        orderTime = string(timeStr);
        // 移除换行符
        if(!orderTime.empty() && orderTime[orderTime.length()-1] == '\n') {
            orderTime.erase(orderTime.length()-1);
        }
    }
};

// 点餐系统类
class OrderSystem {
private:
    vector<MenuItem> menu;
    vector<Order> orders;
    
public:
    OrderSystem() {
        initializeMenu();
    }
    
    void initializeMenu() {
        // 汉堡类
        menu.push_back(MenuItem(1, "经典汉堡", 25.0, "汉堡"));
        menu.push_back(MenuItem(2, "鸡肉汉堡", 28.0, "汉堡"));
        menu.push_back(MenuItem(3, "牛肉汉堡", 32.0, "汉堡"));
        menu.push_back(MenuItem(4, "培根汉堡", 35.0, "汉堡"));
        
        // 小食类
        menu.push_back(MenuItem(5, "薯条(小)", 12.0, "小食"));
        menu.push_back(MenuItem(6, "薯条(大)", 18.0, "小食"));
        menu.push_back(MenuItem(7, "鸡块(6块)", 20.0, "小食"));
        menu.push_back(MenuItem(8, "洋葱圈", 15.0, "小食"));
        
        // 饮品类
        menu.push_back(MenuItem(9, "可乐(中)", 8.0, "饮品"));
        menu.push_back(MenuItem(10, "可乐(大)", 12.0, "饮品"));
        menu.push_back(MenuItem(11, "橙汁", 10.0, "饮品"));
        menu.push_back(MenuItem(12, "咖啡", 15.0, "饮品"));
    }
    
    void showMenu() {
        cout << "\n" << string(60, '=') << endl;
        cout << "                    快餐店菜单" << endl;
        cout << string(60, '=') << endl;
        
        string currentCategory = "";
        for(int i = 0; i < menu.size(); i++) {
            if(menu[i].category != currentCategory) {
                currentCategory = menu[i].category;
                cout << "\n【" << currentCategory << "】" << endl;
                cout << string(30, '-') << endl;
            }
            cout << setw(2) << menu[i].id << ". " 
                 << setw(15) << left << menu[i].name 
                 << "¥" << fixed << setprecision(2) << menu[i].price << endl;
        }
        cout << string(60, '=') << endl;
    }
    
    MenuItem* findMenuItem(int id) {
        for(int i = 0; i < menu.size(); i++) {
            if(menu[i].id == id) {
                return &menu[i];
            }
        }
        return NULL;
    }
    
    void takeOrder() {
        Order newOrder;
        int choice, quantity;
        char continueOrder;
        
        cout << "\n开始新订单..." << endl;
        cout << "订单编号: " << newOrder.orderNumber << endl;
        
        do {
            showMenu();
            cout << "\n请选择商品编号 (1-" << menu.size() << "): ";
            cin >> choice;
            
            MenuItem* item = findMenuItem(choice);
            if(item == NULL) {
                cout << "无效的商品编号,请重新选择!" << endl;
                continue;
            }
            
            cout << "请输入数量: ";
            cin >> quantity;
            
            if(quantity <= 0) {
                cout << "数量必须大于0!" << endl;
                continue;
            }
            
            newOrder.addItem(*item, quantity);
            cout << "已添加: " << item->name << " x" << quantity << endl;
            
            cout << "是否继续点餐?(y/n): ";
            cin >> continueOrder;
            
        } while(continueOrder == 'y' || continueOrder == 'Y');
        
        if(!newOrder.items.empty()) {
            orders.push_back(newOrder);
            cout << "\n订单创建成功!" << endl;
            showOrderSummary(newOrder);
        } else {
            cout << "订单为空,已取消。" << endl;
        }
    }
    
    void showOrderSummary(const Order& order) {
        cout << "\n" << string(50, '=') << endl;
        cout << "                订单汇总" << endl;
        cout << string(50, '=') << endl;
        cout << "订单编号: " << order.orderNumber << endl;
        cout << "下单时间: " << order.orderTime << endl;
        cout << string(50, '-') << endl;
        
        for(int i = 0; i < order.items.size(); i++) {
            const OrderItem& item = order.items[i];
            cout << setw(15) << left << item.item.name 
                 << "x" << setw(2) << item.quantity 
                 << "  ¥" << fixed << setprecision(2) << item.subtotal << endl;
        }
        
        cout << string(50, '-') << endl;
        cout << setw(20) << right << "小计: ¥" << order.totalAmount << endl;
        
        if(order.discount > 0) {
            cout << setw(20) << right << "优惠: -¥" << order.discount << endl;
        }
        
        cout << setw(20) << right << "总计: ¥" << order.finalAmount << endl;
        cout << string(50, '=') << endl;
    }
    
    void showAllOrders() {
        if(orders.empty()) {
            cout << "\n暂无订单记录。" << endl;
            return;
        }
        
        cout << "\n" << string(80, '=') << endl;
        cout << "                        所有订单" << endl;
        cout << string(80, '=') << endl;
        
        for(int i = 0; i < orders.size(); i++) {
            cout << "订单 " << (i+1) << ":" << endl;
            showOrderSummary(orders[i]);
            cout << endl;
        }
    }
    
    void showDiscountRules() {
        cout << "\n" << string(50, '=') << endl;
        cout << "                优惠政策" << endl;
        cout << string(50, '=') << endl;
        cout << "1. 满额优惠:" << endl;
        cout << "   - 满100元减10元" << endl;
        cout << "   - 满200元减25元" << endl;
        cout << "   - 满300元减40元" << endl;
        cout << "\n2. 数量优惠:" << endl;
        cout << "   - 单品数量≥5个,享受9折优惠" << endl;
        cout << "\n注:优惠不可叠加,系统自动选择最优惠方案" << endl;
        cout << string(50, '=') << endl;
    }
    
    void showStatistics() {
        if(orders.empty()) {
            cout << "\n暂无统计数据。" << endl;
            return;
        }
        
        double totalSales = 0.0;
        double totalDiscount = 0.0;
        int totalItems = 0;
        
        for(int i = 0; i < orders.size(); i++) {
            totalSales += orders[i].finalAmount;
            totalDiscount += orders[i].discount;
            totalItems += orders[i].items.size();
        }
        
        cout << "\n" << string(40, '=') << endl;
        cout << "           营业统计" << endl;
        cout << string(40, '=') << endl;
        cout << "总订单数: " << orders.size() << "单" << endl;
        cout << "总销售额: ¥" << fixed << setprecision(2) << totalSales << endl;
        cout << "总优惠额: ¥" << totalDiscount << endl;
        cout << "平均客单价: ¥" << totalSales / orders.size() << endl;
        cout << string(40, '=') << endl;
    }
    
    void run() {
        int choice;
        
        cout << "欢迎使用快餐点餐系统!" << endl;
        
        while(true) {
            cout << "\n" << string(40, '=') << endl;
            cout << "            主菜单" << endl;
            cout << string(40, '=') << endl;
            cout << "1. 查看菜单" << endl;
            cout << "2. 开始点餐" << endl;
            cout << "3. 查看所有订单" << endl;
            cout << "4. 查看优惠政策" << endl;
            cout << "5. 营业统计" << endl;
            cout << "0. 退出系统" << endl;
            cout << string(40, '=') << endl;
            cout << "请选择: ";
            
            cin >> choice;
            
            switch(choice) {
                case 1:
                    showMenu();
                    break;
                case 2:
                    takeOrder();
                    break;
                case 3:
                    showAllOrders();
                    break;
                case 4:
                    showDiscountRules();
                    break;
                case 5:
                    showStatistics();
                    break;
                case 0:
                    cout << "\n感谢使用快餐点餐系统,再见!" << endl;
                    return;
                default:
                    cout << "无效选择,请重新输入!" << endl;
                    break;
            }
        }
    }
};

int main() {
    // 设置控制台输出格式
    cout << fixed << setprecision(2);
    
    OrderSystem system;
    system.run();
    
    return 0;
}

3. 核心功能亮点

🎯 基础功能

  • 分类菜单展示:汉堡、小食、饮品三大类,界面美观清晰
  • 智能点餐流程:支持选择商品、设定数量,自动合并相同商品
  • 实时价格计算:动态计算小计、优惠、总价
  • 精美账单打印:详细订单汇总,包含时间戳和唯一编号

🚀 进阶功能

  • 多订单管理系统:支持并发处理多份订单,历史记录完整保存
  • 智能优惠算法:满额立减 + 数量折扣,系统自动择优
  • 数据统计分析:营业统计、客单价分析、优惠效果评估

二、面向对象设计架构解析

1. 类设计思路

根据面向对象的三大特征:封装、继承、多态,我们将系统设计为四个核心类:

cpp 复制代码
// 核心类设计架构
class MenuItem {     // 菜品类 - 封装商品属性
    int id;
    string name;
    double price;
    string category;
};

class OrderItem {    // 订单项类 - 封装单个商品订购信息
    MenuItem item;
    int quantity;
    double subtotal;
};

class Order {        // 订单类 - 封装整个订单逻辑
    vector<OrderItem> items;
    double totalAmount;
    string orderNumber;
};

class OrderSystem {  // 点餐系统类 - 封装业务逻辑
    vector<MenuItem> menu;
    vector<Order> orders;
};

2. 系统架构可视化

下图展示了四个核心类之间的关系和协作模式:

3. 封装性体现

每个类都严格遵循数据封装原则:

  • 私有数据成员:隐藏内部实现细节
  • 公有接口方法:提供标准化的数据访问方式
  • 职责单一原则:每个类只负责自己领域的业务逻辑
cpp 复制代码
class Order {
private:
    void generateOrderNumber();    // 私有方法:生成订单号
    void generateOrderTime();      // 私有方法:生成时间戳
    
public:
    void addItem(MenuItem item, int quantity);  // 公有接口:添加商品
    void calculateTotal();                      // 公有接口:计算总价
};

三、核心功能实现详解

1. 点餐流程可视化

下图详细展示了用户从查看菜单到完成订单的完整流程:

2. 智能点餐逻辑

商品合并算法:当用户重复点同一商品时,系统会自动合并数量而非创建重复记录

cpp 复制代码
void Order::addItem(MenuItem item, int quantity) {
    // 遍历已有商品,检查是否存在
    for(int i = 0; i < items.size(); i++) {
        if(items[i].item.id == item.id) {
            items[i].quantity += quantity;        // 增加数量
            items[i].subtotal = items[i].item.price * items[i].quantity;
            calculateTotal();                     // 重新计算总价
            return;
        }
    }
    // 如果是新商品,直接添加
    items.push_back(OrderItem(item, quantity));
    calculateTotal();
}

3. 订单编号生成机制

3. 订单编号生成机制

cpp 复制代码
void Order::generateOrderNumber() {
    time_t now = time(0);
    stringstream ss;
    ss << "ORD" << now % 100000;    // 基于时间戳生成唯一编号
    orderNumber = ss.str();
}

4. 菜单分类展示

系统采用动态分类显示方式,根据商品类别自动分组:

cpp 复制代码
void OrderSystem::showMenu() {
    string currentCategory = "";
    for(int i = 0; i < menu.size(); i++) {
        if(menu[i].category != currentCategory) {
            currentCategory = menu[i].category;
            cout << "\n【" << currentCategory << "】" << endl;
        }
        cout << menu[i].id << ". " << menu[i].name 
             << " ¥" << menu[i].price << endl;
    }
}

四、智能优惠系统设计

1. 算法工作原理可视化

下图详细展示了智能优惠算法的完整工作流程:

2. 多重优惠策略

系统实现了双重优惠机制,自动为用户选择最优方案:

满额立减优惠

  • 满100元减10元
  • 满200元减25元
  • 满300元减40元

数量折扣优惠

  • 单品数量≥5个,享受9折优惠

3. 优惠计算算法

cpp 复制代码
void Order::calculateDiscount() {
    discount = 0.0;
    
    // 策略1:满额优惠
    if(totalAmount >= 300) {
        discount = 40.0;
    } else if(totalAmount >= 200) {
        discount = 25.0;
    } else if(totalAmount >= 100) {
        discount = 10.0;
    }
    
    // 策略2:数量优惠(择优选择)
    for(int i = 0; i < items.size(); i++) {
        if(items[i].quantity >= 5) {
            double itemDiscount = items[i].subtotal * 0.1;
            if(itemDiscount > discount) {
                discount = itemDiscount;    // 选择更优惠的方案
            }
        }
    }
}

五、程序运行演示与测试

1. 主界面展示

复制代码
========================================
            主菜单
========================================
1. 查看菜单
2. 开始点餐
3. 查看所有订单
4. 查看优惠政策
5. 营业统计
0. 退出系统
========================================

2. 点餐流程演示

步骤1:选择商品

复制代码
============================================================
                    快餐店菜单
============================================================

【汉堡】
------------------------------
1 . 经典汉堡       ¥25.00
2 . 鸡肉汉堡       ¥28.00
3 . 牛肉汉堡       ¥32.00
4 . 培根汉堡       ¥35.00

【小食】
------------------------------
5 . 薯条(小)       ¥12.00
6 . 薯条(大)       ¥18.00
7 . 鸡块(6块)      ¥20.00
8 . 洋葱圈         ¥15.00

【饮品】
------------------------------
9 . 可乐(中)       ¥8.00
10. 可乐(大)       ¥12.00
11. 橙汁           ¥10.00
12. 咖啡           ¥15.00
============================================================

请选择商品编号: 1
请输入数量: 2

步骤2:订单汇总

复制代码
==================================================
                订单汇总
==================================================
订单编号: ORD87432
下单时间: Thu Jun 05 14:30:25 2025
--------------------------------------------------
经典汉堡        x2   ¥50.00
--------------------------------------------------
                小计: ¥50.00
                总计: ¥50.00
==================================================

3. 优惠效果展示

当订单满足优惠条件时:

复制代码
--------------------------------------------------
                小计: ¥120.00
                优惠: -¥10.00
                总计: ¥110.00
--------------------------------------------------

六、总结与学习拓展

通过本项目的开发,我们深入实践了:

面向对象核心概念

  • 封装:将数据和方法包装在类中,隐藏实现细节
  • 抽象:通过类的设计,将现实世界的概念映射到代码中
  • 模块化设计:每个类承担明确的职责,便于维护和扩展

C++编程技巧

  • vector容器的灵活使用
  • 字符串流stringstream的格式化输出
  • 时间处理函数time()的实际应用
  • 输出格式控制setw()setprecision()的美化效果

这个快餐点餐系统不仅是一个实用的小项目 ,更是面向对象编程 的绝佳实践案例。通过亲自动手实现,你将对C++的类设计对象交互数据封装等核心概念有更深刻的理解。

优秀的程序员不是天生的,而是通过一个个项目历练出来的。从这个点餐系统开始,踏上你的C++进阶之路吧! 🚀

📝 关注我:更多C++实战项目和编程技巧,请关注我的CSDN博客,一起在代码的海洋中探索前行!
创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)

相关推荐
freyazzr13 分钟前
C++八股 | Day2 | atom/函数指针/指针函数/struct、Class/静态局部变量、局部变量、全局变量/强制类型转换
c++
ascarl201018 分钟前
准确--k8s cgroup问题排查
java·开发语言
fpcc1 小时前
跟我学c++中级篇——理解类型推导和C++不同版本的支持
开发语言·c++
莱茵菜苗1 小时前
Python打卡训练营day46——2025.06.06
开发语言·python
爱学习的小道长1 小时前
Python 构建法律DeepSeek RAG
开发语言·python
luojiaao2 小时前
【Python工具开发】k3q_arxml 简单但是非常好用的arxml编辑器,可以称为arxml杀手包
开发语言·python·编辑器
终焉代码2 小时前
STL解析——list的使用
开发语言·c++
SoFlu软件机器人2 小时前
智能生成完整 Java 后端架构,告别手动编写 ControllerServiceDao
java·开发语言·架构
英英_2 小时前
视频爬虫的Python库
开发语言·python·音视频
DevangLic2 小时前
【 *p取出内容 &a得到地址】
c++