Использование контейнеров абстрактного класса для хранения дочерних классов - PullRequest
2 голосов
/ 08 июня 2019

Я хочу, чтобы несколько классов наследовали от этого интерфейса:

class IPlayer {

public:
     virtual ~IPlayer() {}

     virtual void doSomething() = 0;

protected:
     std::string m_name;

};

Вот класс, который должен наследовать от вышеупомянутого:

class Jack : public IPlayer {

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

      ~Jack() { }

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

};

Имейте в виду, что у нас есть другие классыкоторые наследуют от IPlayer таким же образом, например Bob и Alice.

Теперь, скажем, я хотел создать контейнер для Jack s, Bob s и Alices, которые позволили бы мне перегруппировать их в одну переменную.В этом состоянии это невозможно для меня, так как у IPlayer нет ctor, поэтому он не может служить шаблоном для таких объектов, как векторы или списки.(По крайней мере, это мое понимание)

Было бы лучше иметь класс между IPlayer и Jack, который бы реализовывал только ctor и dtor, а затем оставлял бы другие методы чисто виртуальными для использования

ИЛИ

Заставить IPlayer (и / или любой будущий интерфейс) наследовать от того же класса, что и выше, который реализует только ctor и dtor только длясделать IPlayer ctorable для контейнеров?

Ответы [ 2 ]

1 голос
/ 09 июня 2019

На самом деле проблем с этими классами нет. IPlayer может быть абстрактным классом, но вам никогда не нужно создавать экземпляр этого класса. Вы можете прекрасно объявить вектор указателей на IPlayers, если все элементы вектора указывают на неабстрактные подклассы.

Jack* j = new Jack("jack");
std::vector<IPlayer*> v = {j};

Этот код отлично подходит, так как не создается экземпляр IPlayer.

0 голосов
/ 09 июня 2019

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...