Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 装饰图案与超级反图案_C++_Design Patterns_Decorator_Anti Patterns - Fatal编程技术网

C++ 装饰图案与超级反图案

C++ 装饰图案与超级反图案,c++,design-patterns,decorator,anti-patterns,C++,Design Patterns,Decorator,Anti Patterns,让我们来看一个简单的装饰器示例: struct IStuff { virtual void Info()=0; virtual ~IStuff() { } }; class Ugly : public IStuff { public: void Info() { cout << "Ugly"; } }; class Shiny : public IStuff { IStuff* stuff; public: Shiny(IStuff* stuff) {

让我们来看一个简单的装饰器示例:

struct IStuff {
  virtual void Info()=0;
  virtual ~IStuff() { }
};

class Ugly : public IStuff {
public:
  void Info() { cout  << "Ugly"; }
};

class Shiny : public IStuff {
  IStuff* stuff;
public:
  Shiny(IStuff* stuff) {
    this->stuff = stuff;
  }
  ~Shiny() {
    delete stuff;
  }
  void Info() {
    stuff->Info(); // <------------------------------- call super?
    cout << "->Shiny";
  }
};

int main() {
  IStuff* s = new Ugly();
  s = new Shiny(s); // decorate
  s = new Shiny(s); // decorate more
  s->Info(); // Ugly->Shiny->Shiny
  delete s;
  return 0;
}
这也是反模式吗

Call super是一种设计模式,其中一个特定类规定,在派生子类中,用户需要重写一个方法,并在特定点回调被重写的函数本身


这是一个在设计上有什么不同吗?

这不是所谓的超级。调用另一个IStuff实例的Info方法,而不是重写版本

调用超级版本:

struct IStuff {
  // If you override this, you MUST call the base class version <-- call super
  virtual void Info()
  {
    // a default implementation.

    std::cout << "Super call ";  
  }
  virtual ~IStuff() { }
};

class Shiny : public IStuff {
public:
  void Info() {
    IStuff::Info();  // don't forget to call base implementation.
    std::cout << "->Shiny";
  }
};
Decorator的一些实现正在对Decorator基类进行超级调用,该基类负责保存、调用和管理修饰的引用:

struct IStuff 
{
  virtual void Info() = 0;
  virtual ~IStuff() { }
};

class Stuff : public IStuff
{
public:
    void Info() { std::cout << "Basic stuff"; }
};

class StuffDecorator : public IStuff
{
    IStuff* decorated_;
public:
    StuffDecorator(IStuff* decoratedStuff) :
        decorated_(decoratedStuff) {}
    ~StuffDecorator() { delete decorated_; }

    void Info()
    {
        decorated_->Info();
    }
};

class Shiny : public StuffDecorator 
{
public:
  Shiny(IStuff* stuff) : StuffDecorator(stuff) { }

  void Info() 
  {
    StuffDecorator::Info();
    std::cout << "->Shiny";
  }
};
要避免超级调用,您可能需要将Decorator与以下内容结合使用:


这不是所谓的超级。调用另一个IStuff实例的Info方法,而不是重写版本

调用超级版本:

struct IStuff {
  // If you override this, you MUST call the base class version <-- call super
  virtual void Info()
  {
    // a default implementation.

    std::cout << "Super call ";  
  }
  virtual ~IStuff() { }
};

class Shiny : public IStuff {
public:
  void Info() {
    IStuff::Info();  // don't forget to call base implementation.
    std::cout << "->Shiny";
  }
};
Decorator的一些实现正在对Decorator基类进行超级调用,该基类负责保存、调用和管理修饰的引用:

struct IStuff 
{
  virtual void Info() = 0;
  virtual ~IStuff() { }
};

class Stuff : public IStuff
{
public:
    void Info() { std::cout << "Basic stuff"; }
};

class StuffDecorator : public IStuff
{
    IStuff* decorated_;
public:
    StuffDecorator(IStuff* decoratedStuff) :
        decorated_(decoratedStuff) {}
    ~StuffDecorator() { delete decorated_; }

    void Info()
    {
        decorated_->Info();
    }
};

class Shiny : public StuffDecorator 
{
public:
  Shiny(IStuff* stuff) : StuffDecorator(stuff) { }

  void Info() 
  {
    StuffDecorator::Info();
    std::cout << "->Shiny";
  }
};
要避免超级调用,您可能需要将Decorator与以下内容结合使用:


不,它不是调用super,因为你没有调用一个超类,你在调用一个包含的对象。不,它不是调用super,因为你没有调用一个超类,你在调用一个包含的对象。我明白了。我还更新了我的问题,这个问题被接受了,看起来和你的“超级版”一模一样——或者我忽略了什么吗?@JanTuroň你说得对。我编辑了我的答案并提供了一个没有呼叫超级的解决方案。我明白了。我还更新了我的问题,这个问题被接受了,看起来和你的“超级版”一模一样——或者我忽略了什么吗?@JanTuroň你说得对。我编辑了我的答案,并提供了一个没有超级呼叫的解决方案。