static_cast与C风格转换在C++中:该选哪个及为什么?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++ 设计模式:何时使用及为何使用

\n\n

你是否曾因新功能破坏了旧架构而第十次重写代码?或者花费数小时调试,试图找出谁修改了全局变量以及为什么修改?听起来很熟悉?那么欢迎来到设计模式的世界。

\n\n

模式并非万能药。它们是经过实战检验的常见问题解决方案。它们不会让你的代码完美,但会帮助你与其他开发者使用相同的语言交流,并避免成千上万的程序员在你之前已经踩过的坑。

\n\n

在本文中,我们将剖析 C++ 中三大类模式:创建型、结构型 和 行为型。我们将学习何时应用它们,以及何时最好避开它们。开始吧!

\n\n

创建型模式:控制对象的创建

\n\n

创建型模式负责灵活地创建对象。它们隐藏了实例化逻辑,使系统独立于其组件的具体创建方式。

\n\n

单例模式

\n\n

经典模式。它确保一个类只有一个实例,并提供全局访问点。听起来很诱人,但要明智使用 —— 如果单例膨胀成“上帝对象”,它往往会变成反模式。

\n\n

何时使用:日志系统、配置管理器、线程池、硬件交互。

\n\n

C++ 示例(线程安全,C++11 及更新版本):

\n\n
class Logger {\npublic:\n    static Logger& getInstance() {\n        static Logger instance; // 即使在多线程中也只初始化一次\n        return instance;\n    }\n\n    void log(const std::string& msg) {\n        std::cout << "[LOG]: " << msg << std::endl;\n    }\n\n    // 禁止复制和赋值\n    Logger(const Logger&) = delete;\n    Logger& operator=(const Logger&) = delete;\n\nprivate:\n    Logger() = default; // 私有构造函数\n    ~Logger() = default;\n};\n\n// 使用\nLogger::getInstance().log("系统启动");
\n\n

工厂方法

\n\n

定义创建对象的接口,但让子类决定实例化哪个类。当你不确定具体需要哪个类时,它非常有用。

\n\n

何时使用:解析不同格式(JSON、XML、YAML)、为不同操作系统创建 UI 元素、与不同数据库交互。

\n\n

示例:

\n\n
// 抽象产品\nclass Document {\npublic:\n    virtual void open() = 0;\n    virtual ~Document() = default;\n};\n\n// 具体产品\nclass PDFDocument : public Document {\n    void open() override { std::cout << "打开 PDF" << std::endl; }\n};\n\nclass WordDocument : public Document {\n    void open() override { std::cout << "打开 Word" << std::endl; }\n};\n\n// 工厂\nclass Application {\npublic:\n    virtual Document* createDocument() = 0; // 工厂方法\n    virtual ~Application() = default;\n\n    void newDocument() {\n        Document* doc = createDocument();\n        doc->open();\n        delete doc; // 实际代码中应使用智能指针\n    }\n};\n\nclass PDFApp : public Application {\n    Document* createDocument() override { return new PDFDocument(); }\n};\n\n// 使用\nPDFApp app;\napp.newDocument(); // 打开 PDF
\n\n

结构型模式:构建构造器

\n\n

这些模式帮助将类和对象组织成更大的结构,同时保持灵活性和效率。

\n\n

适配器模式

\n\n

允许接口不兼容的对象协同工作。想象一下,你有一个旧库用于处理 XML,但新模块需要 JSON。适配器就是你的救星。

\n\n

何时使用:

博客

书籍推荐