Вызов переопределенной функции из списка ее базового класса?

Допустим, у меня есть пустой класс с виртуальной функцией:

class Base
{
public:
virtual void Foo(){std::cout << "this is the base class";}
}

Тогда у меня есть класс, который наследует от Base и переопределяет Foo():

class Derived : public Base
{
public:
void Foo(){std::cout << "this is the derived class";}
}

Тогда есть какой-то другой класс, который содержит список Base:

class OtherClass
{
public:
std::vector<Base> listOfBases; //note it's not std::list<Derived>
}

Как мне перебрать listOfBases и позвонить Foo() для Derived класс не тот Base учебный класс? Прямо сейчас, если бы я должен был сказать, listOfBases[i].Foo(); затем это базовый класс будет печатать, но я хочу переопределить один из Derived класс для печати.

Я мог бы просто составить список Derived вместо Base и это все исправит, но я буду называть эти унаследованные классы разными вещами, поэтому мне нужен список Base,

Итак, как мне вызвать переопределенную функцию из списка ее базового класса?

1

Решение

Вам нужно использовать список Base* (то есть указатели на базу) или, предпочтительно, std::unique_ptr<Base> или же std::shared_ptr<Base>,

Причина этого кроется в объектной модели C ++ и ее копировании. Производные классы должны быть как минимум такого же размера, как и их базовый класс (они могут быть одинакового размера в зависимости от того, является ли производный класс пустым или нет). Поскольку C ++ использует копирование (или, возможно, перемещение в C ++ 11) при добавлении элементов в vector, он должен выделить достаточно места для п Base объекты. Так как vector почти всегда обертка вокруг простого array, пытаясь добавить (возможно, другого размера) Derived возражать в array из Base объекты неопределенного поведения.

3

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

Получите указатель на каждый базовый класс, а затем уменьшите его до производного класса. Это называется downcast, потому что в UML-диаграмме принято рисовать базовый класс над производным классом.

for ( auto q = listOfBases.begin(); q != listOfBases.end(); ++q )
{
Base* pBase = &(*q); // Get pointer to Base class. Can't downcast on object.
Derived* pDerived = dynamic_cast<Derived*>(pBase); // Downcast
pDerived->Foo();   // Call Foo() of Derived
}
0

По вопросам рекламы [email protected]