Как создать вектор для базовых типов базового класса, чтобы использовать элементы конкретного типа - PullRequest
2 голосов
/ 26 июня 2019

Если сб.могу изменить название на что-то более понятное. Я был бы очень благодарен

Это моя текущая реализация:

std::vector<Zone<sf::CircleShape>*> allZones;                                          
std::vector<Zone<sf::CircleShape>*> estates = initializer->initVillageEstates();       
std::vector<Zone<sf::CircleShape>*> communityAreas = initializer->initCommunityAreas();

Я бы хотел иметь что-то вроде этого:

std::vector<Zone<sf::Shape>*> allZones;                                          
std::vector<Zone<sf::CircleShape>*> estates = initializer->initVillageEstates();       
std::vector<Zone<sf::RectangleShape>*> communityAreas = initializer->initCommunityAreas();

Где CircleShape и RectangleShape являются производными от базового класса Shape.Я думаю, что это было бы возможно для вектора, если бы он был похож на универсальный тип для vector, а не универсальный тип универсальный тип вектора.

Одно решение, котороеприходит в голову то, что я делаю Zone не шаблонным классом, а как ZoneShape и ZoneCircle : public ZoneShape, ZoneRectangle : public ZoneShape.

Таким образом, я мог бы что-то вроде этого:

std::vector<ZoneShape*> allZones;                                          
std::vector<ZoneCircle*> estates = initializer->initVillageEstates();       
std::vector<ZoneRectangle*> communityAreas = initializer->initCommunityAreas();

Я думаю, что это сработает, но я нашел шаблон более чистым для моих целей.Поэтому я должен выяснить, как это может с этим работать.

1 Ответ

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

Чтобы ответить на ваш общий вопрос, нет способа C ++ автоматически заставить шаблоны следовать правилам наследования параметров их типов (некоторые другие языки, такие как Scala, позволяют вам это делать, но они также обычно не работают с типами значений).Что касается C ++, вектор типа A является совершенно отдельным типом от вектора типа B, даже если они оба происходят от одного и того же шаблона.

Похоже, вы понимаете, что, хотя,Что касается альтернатив, создание отдельных ZoneShape классов для каждой фигуры, которую вы можете гипотетически добавить, утомительно (и нарушает DRY), поэтому давайте не будем этого делать.Но если простые старые шаблоны не поддерживают наследование так, как вы хотите, а создание большего количества классов наследования слишком повторяется, вы можете использовать немного обоих миров:

class ZoneShape {
    // Not sure what your Zone class needs to do,
    // but include your functionality based on the
    // base Shape class here.
public:
    virtual void setShape(Shape* shape) = 0;
    virtual Shape* getShape() = 0;
};

template<typename T>
class Zone : public ZoneShape {
protected:
    // Implemented versions of the base type.
    void setShape(Shape* shape) override;
    Shape* getShape() override;

public:
    // Specific to your specific type.
    void setShape(T* t);
    T* getSpecificShape(); // EDIT: This was originally "T* getShape()", 
                           // which cannot be overloaded.
};

std::vector<ZoneShape*> allZones;                                          
std::vector<Zone<sf::CircleShape>*> estates = initializer->initVillageEstates();       
std::vector<Zone<sf::RectangleShape>*> communityAreas = initializer->initCommunityAreas();

Это не идеально (например,Zone<SquareShape>* не обязательно может складываться с Zone<RectangleShape>*), но это должно позволить вам иметь как общие контейнеры для зон всех типов фигур, так и более специализированные контейнеры для определенных форм.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...