C++函数式策略模式代码练习

一.数学运算

1.main.cpp

cpp 复制代码
// main.cpp
#include <iostream>
#include "MathUtils.hpp"

int main() {
    std::cout << "2 + 3 = " << MathUtils::add(2, 3) << std::endl;
    std::cout << "4.5 * 2 = " << MathUtils::multiply(4.5, 2) << std::endl;
    return 0;
}

2.MathUtils.cpp

cpp 复制代码
// MathUtils.cpp
#include "MathUtils.hpp"

int MathUtils::add(int a, int b) {
    return a + b;
}

double MathUtils::multiply(double x, double y) {
    return x * y;
}

3.MathUtils.hpp

cpp 复制代码
// MathUtils.hpp
#pragma once

class MathUtils {
public:
    static int add(int a, int b);
    static double multiply(double x, double y);
};

二.折扣价格

1. DiscountType.hpp

cpp 复制代码
#pragma once
// 正常计费,打折计费,返现计费
enum class DiscountType { CASH_NORMAL, CASH_OEPCENYOFF, CASH_BACK };

2. AcceptCash.hpp

cpp 复制代码
#pragma once
#include "DiscountType.hpp"

// 现金策略接口
class CashStrategy {
public:
    virtual ~CashStrategy() = default;
    virtual double acceptCash(double money) const = 0;
};

double AcceptCash(const DiscountType discountType, const double money);

3. AcceptCash.cpp

cpp 复制代码
#include "AcceptCash.hpp"
#include <cmath>
#include <memory>

// 具体策略类:正常收费
class NormalCharge : public CashStrategy {
public:
    double acceptCash(const double money) const noexcept override {
        return money;
    }
};

// 具体策略类:打折收费
class PercentageDiscount : public CashStrategy {
public:
    double acceptCash(const double money) const noexcept override {
        const double discountRate = 0.9; // 9折
        return money * discountRate;
    }
};

// 具体策略类:返现收费
class Cashback : public CashStrategy {
public:
    double acceptCash(const double money) const noexcept override {
        const double threshold = 100.0; // 每满100返20
        const double cashback = 20.0;
        return money - std::floor(money / threshold) * cashback;
    }
};

double AcceptCash(const DiscountType discountType, const double money)
{
    std::unique_ptr<CashStrategy> strategy;

    switch (discountType) {
        case DiscountType::CASH_NORMAL:
            strategy = std::make_unique<NormalCharge>();
            break;
        case DiscountType::CASH_OEPCENYOFF:
            strategy = std::make_unique<PercentageDiscount>();
            break;
        case DiscountType::CASH_BACK:
            strategy = std::make_unique<Cashback>();
            break;
    }

    return strategy->acceptCash(money);
}

4. main.cpp

cpp 复制代码
#include <iostream>
#include <cassert>
#include <cmath>
#include "AcceptCash.hpp"
#include "DiscountType.hpp"

// 用于比较浮点数的辅助函数
bool nearlyEqual(double a, double b, double epsilon = 1e-9) {
    return std::abs(a - b) < epsilon;
}

int main() {
    // 测试正常收费
    assert(nearlyEqual(AcceptCash(DiscountType::CASH_NORMAL, 100.0), 100.0));

    // 测试打折收费
    assert(nearlyEqual(AcceptCash(DiscountType::CASH_OEPCENYOFF, 100.0), 90.0));

    // 测试返现收费
    assert(nearlyEqual(AcceptCash(DiscountType::CASH_BACK, 100.0), 80.0));   // 100-20=80
    assert(nearlyEqual(AcceptCash(DiscountType::CASH_BACK, 200.0), 160.0));  // 200-40=160
    assert(nearlyEqual(AcceptCash(DiscountType::CASH_BACK, 99.0), 99.0));    // 不足100不返现
    assert(nearlyEqual(AcceptCash(DiscountType::CASH_BACK, 250.0), 210.0));  // 250-50=210

    std::cout << "所有测试通过!" << std::endl;
    return 0;
}

三.配置文件

可参考 C++函数式策略模式中配置修改 详情

1. tasks.json (用于构建和运行)

复制代码
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build and Run",
            "type": "shell",
            "command": "D:/wecode_build_tools/mingw/bin/g++.exe",
            "args": [
                "-std=c++14",
                "main.cpp",
                "AcceptCash.cpp",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}.exe",
                "&&",
                "${fileDirname}/${fileBasenameNoExtension}.exe"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared"
            },
            "problemMatcher": {
                "owner": "cpp",
                "fileLocation": ["relative", "${workspaceFolder}"],
                "pattern": {
                    "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                    "file": 1,
                    "line": 2,
                    "column": 3,
                    "severity": 4,
                    "message": 5
                }
            }
        }
    ]
}

2. settings.json (VS Code设置)

复制代码
{
    "files.associations": {
        "*.h": "cpp",
        "*.hpp": "cpp",
        "iostream": "cpp",
        "array": "cpp",
        "atomic": "cpp",
        "*.tcc": "cpp",
        "cctype": "cpp",
        "clocale": "cpp",
        "cmath": "cpp",
        "cstdarg": "cpp",
        "cstddef": "cpp",
        "cstdint": "cpp",
        "cstdio": "cpp",
        "cstdlib": "cpp",
        "cwchar": "cpp",
        "cwctype": "cpp",
        "deque": "cpp",
        "unordered_map": "cpp",
        "vector": "cpp",
        "exception": "cpp",
        "algorithm": "cpp",
        "memory": "cpp",
        "memory_resource": "cpp",
        "optional": "cpp",
        "string": "cpp",
        "string_view": "cpp",
        "system_error": "cpp",
        "tuple": "cpp",
        "type_traits": "cpp",
        "utility": "cpp",
        "fstream": "cpp",
        "initializer_list": "cpp",
        "iosfwd": "cpp",
        "istream": "cpp",
        "limits": "cpp",
        "new": "cpp",
        "ostream": "cpp",
        "sstream": "cpp",
        "stdexcept": "cpp",
        "streambuf": "cpp",
        "typeinfo": "cpp",
        "random": "cpp",
        "bit": "cpp",
        "bitset": "cpp",
        "chrono": "cpp",
        "condition_variable": "cpp",
        "cstring": "cpp",
        "ctime": "cpp",
        "list": "cpp",
        "map": "cpp",
        "set": "cpp",
        "functional": "cpp",
        "iterator": "cpp",
        "numeric": "cpp",
        "ratio": "cpp",
        "regex": "cpp",
        "future": "cpp",
        "iomanip": "cpp",
        "mutex": "cpp",
        "shared_mutex": "cpp",
        "thread": "cpp",
        "cinttypes": "cpp",
        "complex": "cpp",
        "unordered_set": "cpp",
        "cfenv": "cpp",
        "typeindex": "cpp"
    },
    "files.encoding": "utf8",
    "files.autoGuessEncoding": true,
    "terminal.integrated.shell.windows": "C:\\Windows\\System32\\cmd.exe",
    "terminal.integrated.shellArgs.windows": [
        "/k",
        "D:\\wecode_build_tools\\mingw\\bin\\mingw32-make.exe"
    ],
    "C_Cpp.default.compilerPath": "D:/wecode_build_tools/mingw/bin/g++.exe",
    "C_Cpp.default.cppStandard": "c++14",
    "C_Cpp.default.cStandard": "c17",
    "files.trimTrailingWhitespace": true,
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
        "source.organizeImports": true
    },
    "C_Cpp.intelliSenseEngine": "Default",
    "C_Cpp.errorSquiggles": "Enabled",
    "C_Cpp.autocomplete": "Disabled"
}

四.验证

最后使用的配置可以运行

1.方法1

g++ -std=c++14 -c main.cpp -o main.o #编译_方法1

./cash_program.exe #运行

2.方法2

D:/wecode_build_tools/mingw/bin/g++.exe -std=c++14 main.cpp AcceptCash.cpp -o cash_program.exe #编译_方法2

./cash_program.exe #运行

3.多文件编译

如果有多个文件,比如 MathUtils.cpp,应该:

g++ -std=c++14 main.cpp MathUtils.cpp -o cash_program.exe #多文件编译

./cash_program.exe #运行

补充:.同样的操作,运行的是jianchu文件夹下的为什么报错?

解决:虽然在对应目标文件下,但是编译时将多文件需写正确,再编译

g++ -std=c++14 main.cpp jianchu.cpp -o program.exe

(或者) g++ -std=c++14 main.cpp utils.cpp -o program.exe

最后运行 ./cash_program.exe,

g++ -std=c++14 main.cpp jianchu.cpp -o program.exe

或者 使用

g++ -std=c++14 main.cpp utils.cpp -o program.exe

五.自动化编译运行配置

终端中在编译运行感觉过程繁琐,想减少操作使得一键编译运行,需要哪些配置和操作?

1.安装 C/C++插件(提供智能提示、语法高亮、调试支持等) 和 Code Runner插件(可以一键运行代码,支持多种语言)

2.打开 .cpp 文件,按 Ctrl+Alt+N(或右键 → Run Code),程序自动编译,最后再运行 ./cash_program.exe

整理不易,诚望各位看官点赞 收藏 评论 予以支持,这将成为我持续更新的动力源泉。若您在阅览时存有异议或建议,敬请留言指正批评,让我们携手共同学习,共同进取,吾辈自当相互勉励!

相关推荐
T***16071 小时前
JavaScript打包
开发语言·javascript·ecmascript
qq_336313931 小时前
java基础-常用的API
java·开发语言
道一231 小时前
C# 读取文件方法介绍
开发语言·c#
蒋星熠1 小时前
常见反爬策略与破解反爬方法:爬虫工程师的攻防实战指南
开发语言·人工智能·爬虫·python·网络安全·网络爬虫
是店小二呀1 小时前
在家搭个私人影院?LibreTV+cpolar,随时随地看片自由
开发语言·人工智能
利刃大大2 小时前
【c++中间件】Elasticsearch介绍与安装 && 核心概念 && Kibana && 二次封装
c++·elasticsearch·中间件
catchadmin2 小时前
使用 PHP 和 Raylib 也可以开发贪吃蛇游戏
开发语言·游戏·php
p***43482 小时前
JavaScript数据分析实战
开发语言·javascript·ecmascript