наследование — C ++ Производный класс, переопределяющий член базового класса с другим производным классом?

У меня есть такие классы:

class ParkingLot
{
public:
int spaces;
virtual bool something() { return true; }
}
class ParkingLotBuilding
{
public:
ParkingLot Floor1, Floor2;
}

У меня есть множество функций, которые принимают ParkingLotBuilding. Допустим, кто-то (я) происходит от ParkingLot и ParkingLotBuilding:

class DerivedParkingLot : public ParkingLot
{
public:
virtual bool something() { return false; }
}
class DerivedParkingLotBuilding : public ParkingLotBuilding
{
public:
// how can I make it so that Floor1 and Floor2 are for DerivedParkingLot?
}

У меня есть функции, которые я не контролирую, как это:

CheckBuilding( ParkingLotBuilding &building )
{
if(building.Floor1.something() == true)
// error
}

Если я передам объект DerivedParkingLotBuilding этой функции, как мне сделать так, чтобы он вызывал DerivedParkingLot :: something () для возврата false? Это возможно? Извините, если я не объяснил это правильно, я не уверен, как спросить о проблеме. Спасибо

1

Решение

Как отметил ДжонСмит, вы не можете переопределять элементы данных, только функции-члены. поскольку ParkingLotBuilding содержит ParkingLot ценности, а не ParkingLot указатели или ссылки, они не могут быть использованы полиморфно, даже в DerivedParkingLot, (Именно так работает C ++: только указатели и ссылки могут иметь динамический тип.)

Это означает, что если вы не можете изменить ParkingLotBuilding класс (или CheckBuilding функция), то вы застряли. Вы не можете получить ничего такого, что получит CheckBuilding функция для работы на DerivedParkingLot объект.

Мораль этой истории в том, что классы должны быть разработаны для наследования с самого начала.

0

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

На самом деле вы просто вызываете функцию DerivedParkingLot из экземпляра ParkingLot?

Ваш код уже сделал это, указав метод some как виртуальный, он будет автоматически искать самый низкий метод в своем унаследованном дереве.

Простой способ проверить это состоит в том, чтобы реализовать метод «что-то» в ParkingLot и DerivedParkingLot, поместить в каждое сообщение и проверить его.

0

Один из способов, которым вы могли бы подойти к этому, это сделать ParkingLot шаблон класса.

template<typename T>
class ParkingLotBuilding
{
public:
T Floor1, Floor2;
}

Затем при создании ParkingLotBuildingВы можете использовать эти типы:

ParkingLotBuilding<ParkingLot>
ParkingLotBuilding<DerivedParkingLot>

Также, если вы не любите шаблонизировать все время и хотите просто использовать ParkingLotBuilding а также DerivedParkingLotBuilding, вы можете переименовать класс в нечто вроде Building и используйте typedefs:

typedef Building<ParkingLot> ParkingLotBuilding
typedef Building<DerivedParkingLot> DerivedParkingLotBuilding

Этот подход не совсем наследование между ParkingLotBuilding типы (и, возможно, не лучший подход — я никогда не видел этого раньше), но он может делать то, что вам нужно.

0

В вашем примере, Floor1 не может узнать, был ли он создан внутри ParkingLotBuilding или DerivedParkingLotBuilding.

Вы могли бы использовать RTTI, чтобы иметь дело с этим что-то вроде:

CheckBuilding (ParkingLotBuilding *building)
{
if (dynamic_cast<DerivedParkingLogBuilding*>(building))
{
// Floor is in a derived parking log building
}
else
{
// Floor is in a parking lot building
}
}

Хотя, как указывалось выше, не совсем лучшим было сделать это.

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