C ++:根据变量实例化与许多类型之一相同的对象

时间:2019-07-29 03:00:07

标签: 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的定义有冲突。您可能会明白我要干什么,那么解决这个问题的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

这是多态的用例。

定义一个基类Animation,该基类定义一个共享接口并从中派生各种动画类型。例如:

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