c ++稍后保存说明

问题描述

我正在尝试设计UIDraw方法。我想声明要在主Draw方法中绘制哪些UI元素,但是稍后在代码中有一个单独的UIDraw方法。因此,我需要一种方法来存储要在此新功能中执行的指令。我希望这是有道理的。 像这样:

        Draw();
        DrawUI();

但是说出要在Draw()函数中绘制的UI。 有关如何解决此问题的任何想法?

解决方法

有许多方法可以解决此问题,具体取决于您需要的是什么。在OO世界中流行的一种方法是所谓的Command Pattern(在其他编程范例中也存在类似的方法,它们只是名称不同,或者被认为很明显甚至根本没有一个特定的名称)。 / p>

基本思想是:您想执行某些命令,但是要执行该命令的时间与您决定要执行什么命令的时间不同。因此,解决此问题的方法是简单地创建一个包含执行命令所需信息的对象,将该对象传递到决定执行时间的位置,然后该代码即可根据需要运行命令。

这里是C ++外观的模型(注意:实际上并未编译此代码,可能包含较小的错误-只是为了传达想法)。

#include <memory>
#include <vector>

/// this is an abstract class that gives us an interface to use
class DrawCommand {
  public:
  virtual void Draw() = 0;
};

/// one kind of thing you might want to draw
class DrawTree : public DrawCommand {
  public:
  void Draw() override {
     // tree drawing code
  }
};

/// another kind of thing you might want to draw
class DrawCat : public DrawCommand {
  public:
  void Draw() override {
    // cat drawing code
  }
};

/// we can even come up with ways to combine these in interesting ways
class DrawABunchOfThings : public DrawCommand {
  std::vector<std::unique_ptr<DrawCommand>> things;
  public:
  DrawABunchOfThings(std::vector<std::unique_ptr<DrawCommand>> things)
    : things{std::move(things)}
  {}

  void Draw() override {
    for(auto &thing : things) {
      thing->Draw();
    }
  }
};

/// this is where we decide what we will draw
std::unique_ptr<DrawCommand> PrepareDraw() {
  if(someCondition) {
    // just a cat
    return std::make_unique<DrawCat>();
  } else if(someOtherCondition) {
    // just a tree
    return std::make_unique<DrawTree>();
  } else {
    // forest with a cat hidden inside
    return std::make_unique<DrawABunchOfThings>(
      std::vector<std::unique_ptr<DrawCommand>>{
        std::make_unique<DrawTree>(),std::make_unique<DrawTree>(),std::make_unique<DrawCat>()
        std::make_unique<DrawTree>(),}
    );
  }
}

/// this is where we will do the actual drawing
/// note that any arbitrary amount of code can go between
/// PrepareDraw and ExecuteDraw
void ExecuteDraw(DrawCommand &command) {
  // this can of course have a bunch of elaborate
  // code here as well -- also,DrawCommand::Draw might
  // take extra parameters here,like 2D or 3D transforms,// time since we last drew something,or whatever
  command.Draw();
}

请注意,如果您只需要一个方法,C ++就已经以std::function的形式提供了该方法,因此您只需说出using DrawCommand = std::function<void()>;即可完成操作,这也将立即允许您可以将其与lambda一起使用:

int nTimes = 10;
DrawCommand drawNTimesCommand = [nTimes]() {
  for(int i = 0; i < nTimes; ++i) {
    // draw something
  }
};

// --- any code you like here ---

// actually execute the draw command
drawNTimesCommand();

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...