【问题标题】:Decorator pattern in C++C++ 中的装饰器模式
【发布时间】:2010-06-07 08:41:14
【问题描述】:

谁能给我一个 C++ 中装饰器设计模式的例子? 我遇到过它的 Java 版本,但发现很难理解它的 C++ 版本(从我找到的示例中)。

谢谢。

【问题讨论】:

    标签: c++ design-patterns decorator


    【解决方案1】:

    Vince Huston Design Patterns,尽管它的布局很糟糕,但对于四人帮一书中的大多数设计模式都有 C++ 实现。

    点击Decorator

    与 Java 没有太大区别,除了你最好用智能指针包装的手动内存处理:)

    【讨论】:

    • 这个网站的 +1。我总是参考这个来实现 cpp。我也认为混乱的内存管理是你在 cpp 中看不到这种模式的原因。
    • 我并不总是提及实施,但我很欣赏没有被广告和关于何时应用、何时不应用以及与其他相关模式相比它带来什么的建议发送垃圾邮件。跨度>
    【解决方案2】:

    我发现Sourcemaking 网站对于explaining different Design Patterns 来说是一个相当不错的网站。

    Decorator 设计模式具有 C++ 示例,例如 overview example、“before and after”和 example with packet encoding/decoding

    【讨论】:

    • +1 以获得最佳答案。我检查了那里提供的第二个示例(sourcemaking.com/design_patterns/decorator/cpp/2) - 它不是在接口类(Widget 类)中缺少虚拟析构函数吗?
    • @GuyAvraham - 谢谢。你是对的,基类应该有虚拟析构函数作为一般的“正确做法”。然而,在这个例子中,他们的代码可以正常工作,因为 a)他们没有通过基类指针删除任何对象(他们根本没有删除它们?!?!?他们只是返回/退出,有点草率 ...)和b)派生对象的构造函数'不分配任何资源/打开任何文件等,所以从技术上讲,不调用它们的析构函数不会引起问题......今天。但你是对的——随着代码的增长,这可能会改变。好收获!
    【解决方案3】:
    #include <iostream>
    using namespace std;
    
    class Computer
    {
    public:
        virtual void display()
        {
            cout << "I am a computer..." << endl;
        }
    };
    
    class CDDrive : public Computer
    {
    private:
        Computer* c;
    public:
        CDDrive(Computer* _c)
        {
            c = _c;
        }
        void display()
        {
            c->display();
            cout << "with a CD Drive..." << endl;
        }
    };
    
    class Printer : public Computer
    {
    private:
        CDDrive* d;
    public:
        Printer(CDDrive* _d)
        {
            d = _d;
        }
        void display()
        {
            d->display();
            cout << "with a printer..." << endl;
        }
    };
    
    int main()
    {
        Computer* c = new Computer();
        CDDrive* d = new CDDrive(c);
        Printer* p = new Printer(d);
    
        p->display();
    }
    

    【讨论】:

    • 这是一个很好的解决不同问题的方法,但这不是一个“真正的”装饰器模式,这个设计缺少任何装饰器继承的装饰器类,在这种情况下打印机和 CD 驱动器
    【解决方案4】:

    我最近在学习c++和设计模式,我举一个来自Head First Design Pattern>的例子。

    main.cpp 在这里:

    #include <iostream>
    
    #include "Decaf.h"
    #include "Espresso.h"
    #include "MochaDecorator.h"
    #include "MilkDecorator.h"
    
    using std::cout;
    using std::endl;
    
    
    int main(){
        cout << "---------------------------" << endl;
       
        // only Decaf, no addsOn
        Beverage* decafOnly = new Decaf();
        cout << decafOnly->getDescription() << endl;
        cout << decafOnly->cost() << endl;
        delete decafOnly;
        cout << "---------------------------" << endl;
    
        // Decaf + Mocha
        Beverage* decaf = new Decaf();
        MochaDecorator mocha_decaf = MochaDecorator(decaf);
        cout << mocha_decaf.getDescription() << endl;
        cout << mocha_decaf.cost() << endl;
        delete decaf;
        cout << "---------------------------" << endl;
    
        // Espresso + Milk
        Beverage* espresso = new Espresso();
        MilkDecorator milk_espresso = MilkDecorator(espresso);
        cout << milk_espresso.getDescription() << endl;
        cout << milk_espresso.cost() << endl;
        delete espresso;
        cout << "---------------------------" << endl;
    
        // Note: decorators can wrap not only components but the other decorators as well
    
        // Esresso + Mocha + Milk + Milk,  method 1-------------------------------
        // Beverage* espresso2 = new Espresso();                               // Espresso
        // MochaDecorator* mocha_espresso = new MochaDecorator(espresso2);     // Espresso + Mocha
        // MilkDecorator* milk_deco = new MilkDecorator(mocha_espresso);       // Espresso + Mocha + Milk
        // MilkDecorator* milk_deco2 = new MilkDecorator(milk_deco);           // Espresso + Mocha + Milk + Milk
        // cout << milk_deco2->getDescription() << endl;
        // cout << milk_deco2->cost() << endl;
        // delete espresso2;
        // delete mocha_espresso;
        // delete milk_deco;
        // delete milk_deco2;
    
        // Esresso + Mocha + Milk + Milk,  method 2------------------------------
        Beverage* espresso2 = new MilkDecorator(new MilkDecorator(new MochaDecorator(new Espresso())));
        cout << espresso2->getDescription() << endl;
        cout << espresso2->cost() << endl;
        delete espresso2;
     
        
        cout << "---------------------------" << endl;
        return 0;
    }
    

    其他文件请看我的github:

    https://github.com/jwbecalm/Head-First-Design-Patterns-in-CPP/tree/main/ch03_Decorator

    【讨论】:

      猜你喜欢
      • 2012-02-04
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      • 2021-04-27
      相关资源
      最近更新 更多