Вопрос по oop, c++ – Создание вектора экземпляров разных подклассов

5

Попытка поиска ничего не возвращает (я думаю).

Можно ли сделать вектор абстрактного класса?

Например, у меня есть суперкласс Unit.

И у меня есть солдат подкласса, транспортное средство и бомбардировщик.

Однако я бы хотел, чтобы когда-либо существовал экземпляр любого подкласса в одном векторе, например вектор UnitList может содержать экземпляры как солдата, так и машины?

Это возможно? Я использую C ++, если это помогает.

Ваш Ответ

4   ответа
1

std::vector<Unit> unit_list;
unit_list.push_back(Soldier(params));

Потому что Солдат, Автомобиль и Юнит занимают разные объемы памяти.

Тем не менее, может быть возможно использовать указатели, так как все указатели занимают фиксированный объем памяти:

std::vector<Unit*> unit_list;
unit_list.push_back(new Soldier(params));

Я не проверял это, но в любом случае это имеет смысл в моей голове.

Error: User Rate Limit Exceeded
8

но вам нужно использовать либо указатели, либо умные указатели (я бы с этим согласился).

struct X
{
    virtual ~X() {}  //<--- as pointed out in the comments
                     // a virtual destructor is required
                     // for correct deletion
    virtual void foo() = 0;
};
struct Y : X
{
    virtual void foo() { }
};

int main()
{
    std::vector<X*> a;
    a.push_back(new Y);
    a[0]->foo();
    for ( int i = 0 ; i < a.size() ; i++ )
        delete a[i];
    return 0;
}

Не забудьте удалить выделенную память.

Why you can't use actual objects:

Предполагатьstd::vector<X>, Это незаконно, потому что:

If you want to initialize your vector with some number of elements, the allocation would fail. A vector stores objects internally in continuous memory. A preallocation would fail because it would mean it needed to create objects, which can't be done for abstract classes.

Even if you could, or the base class wasn't abstract, it wouldn't help too much, as you'd suffer from object slicing.

Error: User Rate Limit Exceededstd::unique_ptrError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
2

потому что векторный шаблон должен уметь сообщать компилятору во время компиляции размер его элемента. Тем не менее, вы можете получить то, что вы хотите, сохранив вектор указателей на объекты, а не вектор объектов как таковой.

Update:  Абстрактные классы как таковые имеют известный размер. Это на самом деле экземпляры их наиболее производных типов, размеры которых неизвестны во время компиляции. (Спасибо @LuchianGrigore и @MooingDuck за это.)

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded(thanks @Luchian for pointing this out)Error: User Rate Limit Exceeded
7

правильный способ сделать это - контейнер, содержащий указатели на базовый класс.Unit, (и убедитесь, что у него естьvirtual деструктор.

Опция 1:boost::ptr_vector (требуются библиотеки повышения, которые у вас должны быть в любом случае)

ptr_vector<Unit> units;
units.push_back(new Soldier());

Вариант 2:std::vector<std::unique_ptr<Unit>> (требуется компилятор C ++ 11)

std::vector<std::unique_ptr<Unit>> units;
units.emplace_back(std::unique_ptr<Unit>(new Soldier()));
Error: User Rate Limit Exceededunits.emplace_back(new Soldier())Error: User Rate Limit Exceededpush_backError: User Rate Limit Exceededemplace_back.

Похожие вопросы