У меня есть два класса:
Первый:
class Thing {
public:
int code;
string name;
string description;
int location;
bool canCarry;
Thing(int _code, string _name, string _desc, int _loc, bool _canCarry) {
code = _code;
name = _name;
description = _desc;
location = _loc;
canCarry = _canCarry;
}
};
Во-вторых:
class Door: public Thing {
private:
bool open;
public:
int targetLocation;
Door(int _code, string _name, string _desc, int _loc, int _targetLoc) :
Thing(_code, _name, _desc, _loc, false) {
open = false;
targetLocation = _targetLoc;
}
void Use() {
open = true;
}
void Close() {
open = false;
}
bool isOpen() {
return open;
}
};
Забудьте частные / публичные атрибуты …
Мне нужно хранить некоторые объекты базового класса и некоторые объекты производного класса,
что-то вроде этого:
vector < Thing*> allThings;
things.push_back(new Thing(THING1, "THING1", "some thing", LOC1, true));
things.push_back(new Door(DOOR1, "DOOR1", "some door", LOC1, LOC2));
Но в этом случае функции Use (), Open () и isOpen () не будут доступны из-за нарезки.
У вас есть предложения, как хранить эти объекты вместе, не создавая новую структуру vector<Thing*>
а также vector<Door*>
??
Спасибо
Хорошим решением проблемы, когда вам нужен контейнер объектов с полиморфным поведением, является вектор уникальных указателей:
std::vector<std::unique_ptr<Thing>>
В этой ситуации не было бы нарезки, но вам нужно было бы выяснить, когда можно звонить Use()
, Open()
, а также isOpen()
,
Если вы можете переместить методы из производного класса в базу, сделайте это; если вы не можете сделать это, потому что это не имеет смысла для Thing
иметь isOpen()
рассмотрите возможность использования более продвинутого решения, такого как Шаблон посетителя:
class Thing;
class Door;
struct Visitor {
virtual void visitThing(Thing &t) = 0;
virtual void visitDoor(Door &d) = 0;
};
class Thing {
...
virtual void accept(Visitor &v) {
v.visitThing(*this);
}
};
class Door : public Thing {
...
virtual void accept(Visitor &v) {
v.visitDoor(*this);
}
}
Храните указатели вместо экземпляров и объявляйте открытые и защищенные методы как виртуальные в базовом классе (ах).