动态列表和多态

时间:2019-03-07 15:55:39

标签: c++

我有一个类型为>的映射,该映射中的每个位置都拥有一个子类类型的vector。该系统背后的思想是能够使用add(parentclass *)函数将子项添加到其关联的地图中,并且能够找到其子类型的关联向量。我尝试使用模板和强制转换来使向量识别添加到add函数中的子代的类型,但是没有运气。我不想为每个父母的孩子声明一个添加函数,无论我怎么做,我都必须为每个类型声明一个函数。我可以将它们从地图中删除,但是再有一个问题是调用每个孩子要实现的任何功能。他们没有办法将多态结构的类型匹配到动态分配的列表中吗?

    class Piece
    {
    public:
    pieceType ID;
    //...
    }

    class Infantry :
        public Piece
    {
    public:
    //...
    };

    class Artillery :

        public Piece
    {
    public:
     //...
     };

//...

//In some other classes somewhere

std::map<pieceType, std::vector<Piece*>*> units;
        units.emplace(Infantry_, new std::vector<Infantry*>);
        units.emplace(Artillery_, new std::vector<Artillery*>);

//...
template<typename T>

std::vector<T*> operator+(std::vector<T*> a, Piece * b) {

    a.push_back(static_cast<T*>(b));
    return a;

}

 add(Piece * piece){

units.at(piece->ID) = units.at(piece->ID) + piece;

}

我也知道这段代码有一些错误,更多的是我想说的例子。

2 个答案:

答案 0 :(得分:0)

您必须使用虚拟功能来获取每个子类的ID

class Piece
{
public:
  virtual PieceType ID() const = 0;
}

class Artillery
{
public:
  virtual PieceType ID() const override { /* return your ID for Artillery */ }
}

class Infantery
{
public:
  virtual PieceType ID() const override { /* return your ID for Infantery */ }
}

答案 1 :(得分:0)

std::vector<Piece*>std::vector<Infantry*>std::vector<Artillery*>之间没有任何关系,因此您的地图只能包含std::vector<Piece*>个。

这是有充分理由的。假设您有一个std::vector<Infantry*>,并将指向它的指针放到std::map<pieceType, std::vector<Piece*>*>中。然后,您可以在地图中插入Artillery *

除了直接公开std::vector<Piece*>之外,您还可以公开其(转换为特定子类型)的(只读)视图。

使用范围库

auto asInfantry = ranges::view::transform([](Piece * p){ return static_cast<Infantry *>(p); });
auto asArtillery = ranges::view::transform([](Piece * p){ return static_cast<Artillery *>(p); });

class PieceMap 
{
    std::map<pieceType, std::vector<Piece*>> units;

public:
    auto Infantry() { return units.at(Infantry_) | asInfantry; }
    auto Artillery() { return units.at(Artillery_) | asArtillery; }
};