繁体   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