c++ - 如何从 vector 中返回给定类型的元素?

标签 c++ polymorphism rtti dynamic-cast

我有一个类,EscapeRoomWrapper,以及从它派生的两个类,ScaryRoomKidsRoom

在另一个类 Company 中,我添加了一个指向所有房间对象的指针的 vector(EscapeRoomWrapperScaryRoomKidsRoom)。我想在 Company 类中编写一个函数,在其中我给它一种房间类型,它应该返回所有存在于 vector 中的该类型的所有房间房间。

我想过使用typeid,但是教授禁止我们使用它。我最后的想法是使用 dynamic_cast

typedef enum{
    SCARY_ROOM, KIDS_ROOM, BASE_ROOM
}RoomType;

class Company{
    string CompanyName;
    std::vector<EscapeRoomWrapper*> Rooms;

public:
    std::vector<EscapeRoomWrapper*>& getAllRoomsByType(RoomType type) const;
};

class EscapeRoomWrapper{
    EscapeRoom room;
    std::vector<Enigma> Enigmas;
public:
    // functions here
};

class ScaryRoom : public EscapeRoomWrapper {
private:
    int ageLimit;
    int NumOfScaryEnigmas;
public:
    // functions for escary room
};

class KidsRoom : public EscapeRoomWrapper {
private:
    int ageLimit;
public:
    // functions for kidsroom
};

关于如何实现此功能的任何想法?

std::vector<EscapeRoomWrapper*>& getAllRoomsByType(RoomType type) const

最佳答案

认为可以使用 dynamic_cast 是正确的,例如:

class Company {
    ...
    std::vector<EscapeRoomWrapper*> Rooms;
public:
    std::vector<EscapeRoomWrapper*> getAllRoomsByType(RoomType type) const;
};

std::vector<EscapeRoomWrapper*> Company::getAllRoomsByType(RoomType type) const
{
    std::vector<EscapeRoomWrapper*> result;

    switch (type) {
        case SCARY_ROOM:
            for (size_t i = 0; i < Rooms.size(); ++i) {
                if (dynamic_cast<ScaryRoom*>(Rooms[i])) {
                    result.push_back(Rooms[i]);
                }
            } 
            break;

        case KIDS_ROOM:
            for (size_t i = 0; i < Rooms.size(); ++i) {
                if (dynamic_cast<KidsRoom*>(Rooms[i])) {
                    result.push_back(Rooms[i]);
                }
            } 
            break;

        case BASE_ROOM:
            result = Rooms;
            break;
    }

    return result;
}

但是,dynamic_cast 有一些运行时开销,它取决于为类生成 RTTI 的编译器(默认情况下会这样做,但可以 禁用)。还有其他可用的解决方案。

您可以定义一个虚函数让每个类从 enum 报告其类型,然后您可以查看这些类型值:

class EscapeRoomWrapper {
    ...
public:
    ...
    virtual RoomType getRoomType() const { return BASE_ROOM; }
};

class ScaryRoom : public EscapeRoomWrapper {
    ... 
public:
    ...
    RoomType getRoomType() const { return SCARY_ROOM; }
};

class KidsRoom : public EscapeRoomWrapper {
    ... 
public:
    ...
    RoomType getRoomType() const { return KIDS_ROOM; }
};

std::vector<EscapeRoomWrapper*> Company::getAllRoomsByType(RoomType type) const
{
    std::vector<EscapeRoomWrapper*> result;

    for (size_t i = 0; i < Rooms.size(); ++i) {
        if ((Rooms[i]->getRoomType() == type) || (type == BASE_ROOM)) {
            result.push_back(Rooms[i]);
        }
    }

    return result;
}

或者,您可以只为每种房间类型存储单独的列表:

class Company {
    ...
    std::vector<EscapeRoomWrapper*> ScaryRooms;
    std::vector<EscapeRoomWrapper*> KidsRooms;
    std::vector<EscapeRoomWrapper*> AllRooms;
public:
    std::vector<EscapeRoomWrapper*> getAllRoomsByType(RoomType type) const;
};

std::vector<EscapeRoomWrapper*> Company::getAllRoomsByType(RoomType type) const
{
    switch (type) {
        case SCARY_ROOM:
            return ScaryRooms;

        case KIDS_ROOM:
            return KidsRooms;

        case BASE_ROOM:
            return AllRooms;
    }

    return std::vector<EscapeRoomWrapper*>();
}

关于c++ - 如何从 vector 中返回给定类型的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44791846/

相关文章:

c++ - 使用 SDL2 和 OpenGL 使用 SDL TTF 显示文本

c++ - std::sort_heap 按降序排列

c++ - struct不继承虚函数

c++ - 使用 `dynamic_cast` 来推断在基类上定义并在派生类上实现的成员函数的参数类型是否正确?

delphi - 固定枚举未返回 RTTI 属性 : is it a bug?

c++ - 通过删除点链接和重复的斜线规范化 Unix 文件路径

c++ - 是否有 split_copy 或某种快捷方式

C++ 构造函数成员初始化列表,对象切片

delphi - 通过 TRttiProperty.SetValue 分配对象过程时会引发 EInvalidCast 异常

德尔福7 : create a new instance of an unknown object