使用抽象容器 class 来容纳 children classes

Using containers of abstract class to hold children classes

我想要几个class继承这个接口:

class IPlayer {

public:
     virtual ~IPlayer() {}

     virtual void doSomething() = 0;

protected:
     std::string m_name;

};

这里有一个class需要继承上面的:

class Jack : public IPlayer {

public:
      Jack(std::string t_name)
      {
             m_name = t_name;
      }

      ~Jack() { }

      void doSomething()
      {
              /* do a bunch of stuff */
      }

};

请记住,我们还有其他 class 以相同的方式从 IPlayer 继承,例如 BobAlice

现在假设我想为 Jacks、Bobs 和 Alices 创建一个容器,这样我就可以将它们重新组合到同一个变量中。在这种状态下,这对我来说是不可能的,因为 IPlayer 没有构造函数,因此不能用作 objects 的模板,例如向量或列表。 (至少这是我的理解)

有一个 class in-between IPlayerJack 会更好吗?它们只实现 ctor 和 dtor,然后将其他方法留给纯虚拟的被 children;

利用

使 IPlayer(and/or 任何未来的接口)从与上面相同的 class 继承,仅实现 ctor 和 dtor 只是为了使 IPlayer 可用于容器?

其实这些class是没有问题的。 IPlayer 可能是一个抽象 class,但您永远不需要创建此 class 的实例。只要向量的元素都指向非抽象 sub-classes.

,您就可以完美地声明一个指向 IPlayers 的指针向量
Jack* j = new Jack("jack");
std::vector<IPlayer*> v = {j};

这段代码非常好,因为没有创建 IPlayer 的实例。

IPlayer 可以有一个构造函数,实际上有一个是由编译器提供的。

这是一种将播放器列表保存在 IPlayer 静态成员中的方法。但列表不必在 IPlayer 中。

#include <memory>
#include <vector>

// forward declaration
class IPlayer;

using Players = std::vector<PlayerPtr>;

class IPlayer {
public:
    virtual ~IPlayer() {
    }
    static void addPlayer(IPlayer& player) {
        mPlayers.push_back(std::make_unique<IPlayer>(player));
    }
private:
    static Players mPlayers;
};

Players IPlayer::mPlayers;

class Bob : public IPlayer {
};

void run() {
    Bob bob;
    IPlayer::addPlayer(bob);
}