C ++ хранит базовый и производный класс объектов вместе

У меня есть два класса:

Первый:

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*>??

Спасибо

3

Решение

Хорошим решением проблемы, когда вам нужен контейнер объектов с полиморфным поведением, является вектор уникальных указателей:

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

Другие решения

Храните указатели вместо экземпляров и объявляйте открытые и защищенные методы как виртуальные в базовом классе (ах).

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector