C++:根据变量将同一对象实例化为多种类型之一

标签 c++ object switch-statement delete-operator

我正在为我设计的 LED 立方体编程。立方体有一个“暂停”按钮和一个“播放/下一步”按钮。除非立方体暂停,否则它将循环播放我为它制作的所有不同效果(动画)。如果按下暂停按钮,立方体将不再在效果之间转换,而是重复当前效果。按“播放/下一个”按钮将取消暂停功能并立即前进到下一个效果。

其中一些效果非常复杂,需要在动画帧之间保留大量变量。为了立即轻松销毁所有这些变量(比如按下下一个按钮时),我将当前动画实例化为一个对象,并在效果完成或按下跳过按钮时销毁它。

我正在尝试按如下方式设置我的主循环:

void loop() {
  //create an effect object
  switch(effectIndex){
    case 0:
    EF_GROWFRAME effect;
    break;
    case 1:
    EF_RANDOMFILL effect;
    break;
  }

  bool proceed;

  do{
    //returns false until the effect has completed
    proceed=effect.step();
    //push this cube update and wait for it to display
    cube.update();
    cube.waitForFrame();
  }
  while ((!proceed)&&(!skipflag));
  //skipflag is set true during a timer interrupt if the skip button is freshly pressed
  skipflag=false;
  cube.clearPattern();

  if (play) effectIndex++;
  if (effectIndex=effectCount) effectIndex=0;
}

虽然我对 effect 的定义有冲突,但它失败了。您可能会明白我要做什么,那么处理这个问题的正确方法是什么?

最佳答案

这是多态性的一个用例。

定义一个基类 Animation,它定义了一个共享接口(interface)并让您的各种动画类型从中派生。例如:

class Animation {
public:
    virtual ~Animation() {
        // any generic cleanup shared by all animation types
    }
    virtual bool step() = 0;
};

class AnimationA : public Animation {
public:
    bool step() override {
        // logic for this type of animation
    }
};

class AnimationB : public Animation {
public:
    bool step() override {
        // logic for this type of animation
    }
};

void loop() {
    std::unique_ptr<Animation> effect;

    switch (effectIndex) {
    case 0:
        effect = std::make_unique<AnimationA>();
        break;
    case 1:
        effect = std::make_unique<AnimationB>();
        break;
    }

    //...
}

Live Demo


因为这似乎是一个嵌入式环境,您可以通过将动画播放逻辑分解到一个单独的函数中来避免我第一个示例中的动态内存分配:

void playAnimation(Animation& effect) {
    bool proceed;

    do{
        //returns false until the effect has completed
        proceed=effect.step();
        //push this cube update and wait for it to display
        cube.update();
        cube.waitForFrame();
    } while (!proceed && !skipFlag);
    //skipflag is set true during a timer interrupt if the skip button is freshly pressed
    skipflag=false;
    cube.clearPattern();
}

void loop() {
    switch (effectIndex) {
    case 0:
        {
            AnimationA effect;
            playAnimation(effect);
            break;
        }
    case 1:
        {
            AnimationB effect;
            playAnimation(effect);
            break;
        }
    }

    if (play) effectIndex++;
    if (effectIndex == effectCount) effectIndex=0;
}

Live Demo

关于C++:根据变量将同一对象实例化为多种类型之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57246729/

相关文章:

javascript - 创建一个 JavaScript 对象

java - 在 Java 中传递对象引用的问题

java - Java 的 switch 在底层是如何工作的?

c++ - PIMPL 习语 VS 前向声明

c++ - Fortran 将字符*81 数组传递给 C/C++ 代码

javascript - 为什么添加 "{" "}"会从数组中删除括号? (JavaScript)

PHP - switch case 中 break 和 continue 的区别

c++ - 具有协变返回类型和模板类参数的虚拟继承,vs2013 中的 LINK 错误

c++ - 通过 std::enable_if_t 传递被调用方法的返回值

java - 空对象引用上的“void android.widget.Switch.setOnCheckedChangeListener(android.widget.CompoundButton$OnCheckedChangeListener)”?