有效管理单个元素或元素数组的相同代码

时间:2015-02-18 03:38:30

标签: c++ templates c++11

我有一个有很多方法的大班。该类有一个子类来管理不同的情况。

只是用一个例子来清理它,实际情况如下:

class Logic {
public:
  virtual void method()
  {
    Something::getInstance()->doSomething();
  }
};

class ArrayLogic : public Logic {
private:
  Something** array;

public:
  void method() override
  {
    for (int i = 0; i < AMOUNT; ++i)
      array[i]->doSomething();
  }
};

现在这个模式在多种方法中重复出现,我希望只有一个实现而不进行性能交易(因为有些方法实际上已经证明需要提高效率)。

我在想C ++ 11是否可以使用模板解决方案,这种方法能够在编译时管理这种情况,而无需复制代码。

请注意arrayLogic的存在没有意义,因此拥有Something*[1]不是一个可行的选择。

另一个问题是,目前Something**数组并非直接包含在ArrayLogic中,而是存在于另一个类中,因此它更像

class ArrayLogic : public Logic {
private:
  Container* container;

public:
  void method() override {
    for (int i = 0; i < AMOUNT; ++i)
      if (container->array[i])
        container->array[i]->doSomething();
  }
}

虽然必须检查container->array[i] != nullptr可能看起来很奇怪但事实是位置是相关的,因此从数组中移除的元素不会导致连续元素的移位但会留下一个洞。 / p>

1 个答案:

答案 0 :(得分:0)

我会尝试为单人和多人游戏创建单独的课程。将这两者都基于LogicBase基类,该基类具有method(Something*)函数,该函数在其参数上调用doSomething()。这就是@Pradhan所指的。

在您的主游戏中,您可以使用LogicBase*来引用SinglePlayerLogicMultiPlayerLogic对象,并使用虚拟函数调用来调用相关的method()

我将Container中存储的内容传递给MultiPlayerLogic的构造函数。但它可以在一个单独的类中,并以这种方式访问​​。同样,将Something传递给SinglePlayerLogic的构造函数可能更清晰,但我想保持代码结构接近原始代码,所以没有这样做。

最初看起来很有趣LogicBase调用子类,然后让这些子类在超类中调用受保护的method(Something*)。我在其他地方看到它作为一种设计模式,但不记得它的名字。

#include <iostream>
#include <vector>

const int AMOUNT = 5;

struct Something {
    void doSomething() { std::cout << "Something::doSomething\n"; }

    static Something* getInstance() { static Something s; return &s; }
};

class LogicBase {
public:
    virtual void method() = 0;

protected:
    void method(Something* s) { s->doSomething(); }
};

class SinglePlayerLogic : public LogicBase {
public:
    void method() override
    {
        std::cout << "SinglePlayer::method\n";
        LogicBase::method(Something::getInstance());
    }
};

class MultiPlayerLogic : public LogicBase {
public:
    MultiPlayerLogic(Something **s) : players(s) {}

    void method() override
    {
        std::cout << "MultiPlayer::method\n";
        for (int i = 0; i < AMOUNT; ++i) {
            if (players[i] == nullptr) {
                continue;
            }

            std::cout << i << " ";
            LogicBase::method(players[i]);
        }
    }

private:
    Something** players;
};

int main() {
    LogicBase* lb;

    SinglePlayerLogic spl;

    lb = &spl;
    lb->method();

    std::vector<Something*> players{AMOUNT};
    MultiPlayerLogic mpl(players.data());

    lb = &mpl;
    lb->method();
}