c++ - 如何为基类泛型类型创建 vector 以使用具体类型元素

标签 c++ c++11 vector

如果某人。可以将标题更改为更容易理解的内容我将非常感谢

这是我当前的实现:

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 的 generic type 的通用类型,那么这对于 vector 来说是可能的。

我想到的一个解决方案是,我将 Zone 设置为不是模板类,而是像 ZoneShapeZoneCircle : public ZoneShape, ZoneRectangle : public ZoneShape.

这样我就可以做这样的事情:

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

我认为这可行,但我发现模板对于我的目的来说更简洁。所以我必须弄清楚这如何与它一起工作。

最佳答案

要回答您的总体问题,没有 C++ 方法可以自动使模板遵循其类型参数的继承规则(其他一些语言,如 Scala 可以让您这样做,但它们通常也不使用值类型)。就 C++ 而言,类型 A 的 vector 与类型 B 的 vector 是完全不同的类型,即使它们都来自同一模板。

不过,听起来您似乎意识到了这一点。就替代方案而言,单独制作 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>* 叠加),但它应该允许您拥有用于所有形状类型区域的通用容器以及用于特定形状的更专用容器。

关于c++ - 如何为基类泛型类型创建 vector 以使用具体类型元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56762744/

相关文章:

c++ - EnumDisplaySettings 最大模式数

C++ 检查构造函数是否包含给定类型的参数

c++ - 了解 std::copy

c++ - 删除 vector 中的所有元素,直到第一个非零元素 C++

c++ - 是否可以使用互斥锁来锁定 vector 中的元素而不是整个 vector ?

c++ - Turbo C++ 和 Dev-C++ 中 C 和 C++ 语言的标识符的最大长度

c++ - 动态内存和链表

c++ - 指向成员函数的函数指针

c++ - 从参数中扣除数组长度

python - 如何在 Tkinter Canvas 上旋转多边形?