简体   繁体   English

如何为基类泛型类型创建向量以使用具体类型元素

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

If sb.如果某人。 can change the title to something more understandable I'd be very thankful可以将标题更改为更容易理解的内容,我将非常感谢

This is my current implementation:这是我目前的实现:

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

I'd love to have something like this:我很想有这样的东西:

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

Where CircleShape and RectangleShape derive from the base class Shape .其中CircleShapeRectangleShape派生自基类Shape I think that would be possible for a vector if this would be like the generic type for the vector and not the generic type of the generic type of the vector.我认为这对于向量来说是可能的,如果这类似于vector的泛型类型而不是vector的泛型类型的泛型类型

One solution that comes in mind is that I make Zone not a template class but like ZoneShape and ZoneCircle : public ZoneShape , ZoneRectangle : public ZoneShape .想到的一个解决方案是,我使Zone不是模板类,而是像ZoneShapeZoneCircle : public ZoneShapeZoneRectangle : public ZoneShape

That way I could to something like this:这样我就可以做这样的事情:

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

I think that would work but I kinda found the template way more clean for my purpose.我认为这会起作用,但我觉得模板方式更适合我的目的。 So I have to figure out how this might work with that.所以我必须弄清楚这如何与它一起工作。

To answer your overall question, there's no C++ way to automatically make templates follow the inheritance rules of their type parameters (some other languages like Scala will let you do this, but they're also generally not working with value types).为了回答您的整体问题,没有 C++ 方法可以自动使模板遵循其类型参数的继承规则(Scala 等其他一些语言可以让您这样做,但它们通常也不适用于值类型)。 As far as C++ is concerned, a vector of type A is a completely separate type from a vector of type B, even though they're both descended from the same template.就 C++ 而言,类型 A 的向量与类型 B 的向量是完全不同的类型,即使它们都来自同一个模板。

It sounds like you realize that, though.不过,您似乎意识到了这一点。 As far as alternatives go, making separate ZoneShape classes for every single shape you might want to hypothetically add is tedious (and violates DRY), so let's not do that.就替代方案而言,为您可能想要添加的每个形状创建单独的ZoneShape类是乏味的(并且违反 DRY),所以我们不要这样做。 But if plain old templates don't support inheritance the way you want, and making more class inheritance is too repetitive, you could make use of a bit of both worlds:但是如果普通的旧模板不支持你想要的继承方式,并且创建更多的类继承太重复了,你可以利用两个世界:

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

It's not perfect (eg a Zone<SquareShape>* cannot necessarily stack with a Zone<RectangleShape>* ), but it should allow you to have both generic containers for zones of all shape types as well as more specialized containers for specific shapes.它并不完美(例如Zone<SquareShape>*不一定与Zone<RectangleShape>*堆叠),但它应该允许您拥有用于所有形状类型区域的通用容器以及用于特定形状的更专业的容器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何创建一个向量来保存同一模板类的所有类型的元素 - How to create a vector that saves elements of all types of the same template class 验证多态向量元素的具体类型是相同的 - Veryfing that concrete types of polymorphic vector elements are the same 将在抽象基类上定义的向量的元素与具体派生类进行匹配 - Match the elements of a vector defined over an abstract base class against a concrete derived class 如何使用向量作为基类 - How do you use vector as a base class 如何使用抽象类型的C ++指针指向具体的类? - How to use a C++ pointer of abstract type to point to a concrete class? 如何在基类指针向量的元素上应用重载的多态函数 - How to apply overloaded polymorphed function on elements of base class pointer vector 如何在类型未知的类内使用通用向量 - How to have a generic vector inside a class for which the type is unknown 如何从模板类创建具体类 - How to create concrete class from a template class 如何找到包含在多态基类向量中的对象的类型? - how to find type of an object contained in a vector of polymorphic base class? 实现类型为vector的元素 - Implementing elements of a vector of type class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM