2017-06-28 3 views
0

Ich habe eine Klasse, EscapeRoomWrapper, und zwei Klassen, die davon abgeleitet sind, ScaryRoom und KidsRoom.Wie Elemente eines bestimmten Typs von einem Vektor zurückgegeben werden?

In einer anderen Klasse, Company, fügte ich ein vector von Zeigern auf alle Raumobjekte (EscapeRoomWrapper, ScaryRoom und KidsRoom). Ich möchte eine Funktion in der Company Klasse schreiben, wo ich es eine Art von Zimmer geben und es sollte alle Zimmer dieses Typs, die in der vector aller Zimmer existieren, zurückgeben.

Ich dachte über die Verwendung typeid, aber der professer verbot uns, es zu verwenden. Meine letzte Idee ist es, dynamic_cast zu verwenden.

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 
}; 

Irgendwelche Ideen, wie ich diese Funktion implementieren kann?

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

Um Jasmin, Sorry, ich storniere Ihre Bearbeitung meiner schlechten. – Stargateur

+0

es ist ok danke für die Bearbeitung – jasmin

+0

Sie könnten eine enum aller Typen erstellen, die Sie haben, und einer Klasse zuweisen und diesen Weg wählen. Es ist billiger als ein String vergleichen. * Achselzucken * –

Antwort

1

Sie sind auf dem richtigen Weg durch das Denken Sie dynamic_cast verwenden können, zum Beispiel:

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; 
} 

Aber dynamic_cast einige Laufzeit-Overhead hat, und es hängt von der Compiler RTTI für die Klassen produzieren (die es tut standardmäßig, aber das kann deaktiviert werden). Es gibt andere verfügbare Lösungen.

Sie können eine virtuelle Funktion definieren jede Klasse ihre Art berichten von der enum haben und dann können Sie an diesen Typ Werte aussehen:

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; 
} 

Oder könnten Sie einfach speichern separate Listen für jeden Zimmertyp:

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*>(); 
} 
+0

Ich werde weinen! thnk du so so sehr, ich kann dir nicht genug dafür danken !!! – jasmin

Verwandte Themen