簡體   English   中英

如何為基類泛型類型創建向量以使用具體類型元素

[英]How to create a vector for base class generic types to use concrete type elements

如果某人。 可以將標題更改為更容易理解的內容,我將非常感謝

這是我目前的實現:

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();

其中CircleShapeRectangleShape派生自基類Shape 我認為這對於向量來說是可能的,如果這類似於vector的泛型類型而不是vector的泛型類型的泛型類型

想到的一個解決方案是,我使Zone不是模板類,而是像ZoneShapeZoneCircle : public ZoneShapeZoneRectangle : public ZoneShape

這樣我就可以做這樣的事情:

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

我認為這會起作用,但我覺得模板方式更適合我的目的。 所以我必須弄清楚這如何與它一起工作。

為了回答您的整體問題,沒有 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>*堆疊),但它應該允許您擁有用於所有形狀類型區域的通用容器以及用於特定形狀的更專業的容器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM