Во-первых, если этот код взят из книги, тогда получите другую книгу:
- Я понимаю, что это иллюстрирует преднамеренную ошибку в публичном извлечении BagOfApples из BagOfFruit (что бессмысленно, поскольку публичное получение означает, что люди могут продолжать использовать BagOfApples как BagOfFruit, тем самым вставляя в него объекты, которые являются не яблоки) НО
- Это пронизано другой проблемой и плохим дизайном:
- Владение фруктами никогда не захватывается контейнерами с пакетами ... они принимают ссылки на объекты, а затем принимают их адрес. Не имея
insert()
указателя, они ложно подразумевают, что объект копируется по значению. Этот пользовательский интерфейс подвержен ошибочному использованию приложения при сбое.
- Сам Страуструп сказал, что спецификации исключений оказались ошибкой и не должны использоваться (я постараюсь найти ссылку на стенограмму интервью в Интернете, если кто-то действительно заинтересован и не может найти себя).
- Метод
remove()
обманчив, так как возвращает значение. В литературе Comp Sci для этого обычно используется термин pop()
.
но вопрос в том, что на самом деле происходит в этой строке:
{ return (Apple&) BagOfFruit::remove(); }//what does happen here?
Ну, remove()
"выталкивает" фрукты из сумки / контейнера, и бросок в стиле C просто обещает компилятору, что этот вытолкнутый фрукт - это Apple
. Это, вероятно, будет правильным, если мешок используется исключительно через специфичный для BagOfApples интерфейс, но, учитывая, что он публично происходит от BagOfFruit, для некоторого кода вполне возможно использовать его в качестве BagOfFruit и вставлять в него какой-либо другой тип фруктов. Если возвращается Apple&
, но объект не является Apple
, и кто-то пытается оперировать предполагаемым Apple
, то у вас будет неопределенное поведение.
На практике этот код, вероятно, будет работать, как и ожидалось, для большинства реальных реализаций компилятора. Но, скажем, яблоко добавляет члена «const char *» для хранения региона, где он вырос. Допустим, вы идете печатать или сравнивать регион, но объект действительно Banana
: компилятор может переосмыслить биты со значениями ar[0]
и, возможно, ar[1]
(для 32-битных и 64-битных систем) как const char*
, затем попытайтесь использовать строку по этому бессмысленному адресу. Это может привести к ошибке сегментации и крушению вашей программы. Но помните, что даже если это не звучит так, как будто вас укусят от вашего точного использования, поведение технически не определено и может быть хуже.