|
Заблокирован
|
||||||
Неочевидные грабли полиморфизма с++23.11.2011, 01:05. Показов 16476. Ответов 101
Метки нет (Все метки)
Наткнулся в интернете на любопытный код.
Спешу поделиться с сообществом. Просто, что бы кто если не в курсе - узнал, и не попал на эти грабли:
Но в любом случае, нужно быть предельно осторожным. А по сути, полиморфизм + множественное наследование = мина замедленного действия. Поэтому, при проектировании полиморфных классов, лучше до последнего избегать множественного наследования.
1
|
||||||
| 23.11.2011, 01:05 | |
|
Ответы с готовыми решениями:
101
Грабли с кодировкой |
|
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
||
| 23.11.2011, 12:51 | ||
|
0
|
||
|
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
||||
| 23.11.2011, 13:07 | ||||
|
Добавлено через 1 минуту Добавлено через 7 минут
0
|
||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||
| 23.11.2011, 13:08 | ||
|
int* - указатель типа int int - просто тип инт Слово "указатель" семантично равнозначно добавлению * к названию типа. Т.е. "тип int*" и "указатель на тип int" это одно и то же.
0
|
||
|
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
| 23.11.2011, 13:08 | |
|
0
|
|
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||
| 23.11.2011, 13:10 | ||
|
0
|
||
|
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|||||||||||||||
| 23.11.2011, 13:18 | |||||||||||||||
Добавлено через 36 секунд Добавлено через 1 минуту Добавлено через 49 секунд
0
|
|||||||||||||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|||||||||||||
| 23.11.2011, 13:25 | |||||||||||||
Впрочем беседа уже свелась к тому, называть фигуру "квадрат" или "равносторонний прямоугольник"... Добавлено через 28 секунд
0
|
|||||||||||||
|
Заблокирован
|
|||||||
| 24.11.2011, 09:00 [ТС] | |||||||
|
Всегда считал, что int* это и есть указатель Сам по себе указатель - это и есть тип. Другое дело, что переменная типа указатель содержит адрес объекта. И эту переменную так же называют указателем.
О том, что на самом деле он смотрит на объект типа C знают только программисты, да может быть всякие там динамик_касты. Компилятор же считает, что указатель_на_тип априори указывает на объекты такого же типа. Указатель_на_тип - нужно понимать, как тип самого указателя. По сабжу, есть только два варианта: 1 Либо забить на производительность и юзать динамик_касты. 2 Либо программист сам отдаёт отчет в том, куда в каждый момент времени смотрят указатели, и какие там на самом деле живут объекты. И не допустить срезки. Самый простой способ добиться такого эффекта - не юзать множественное наследование при полиморфизме. И вообще не делать глубоких/широких наследований. Тогда не придётся втыкать в низко-уровневую работу полиморфизма.
0
|
|||||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|||
| 24.11.2011, 09:13 | |||
|
Добавлено через 1 минуту Вернее - нет.) int* это тип, а переменная этого типа - указатель. Добавлено через 2 минуты 2. Нет. Программист не должен об этом думать. Если он должен об этом думать, скорее всего это ошибка проектирования. Срезка бывает только при использовании значений. При использовании указателей и ссылок срезки не бывает.
0
|
|||
|
Заблокирован
|
||
| 24.11.2011, 09:23 [ТС] | ||
|
по сабжу, именно поэтому и происходила срезка - использовался указатель на А, ну или на Б, без учета того, на что действительно смотрел указатель. А как это вообще получилось? У человека была самодельная фабрика, которая производила объекты типа ЦЕ, а наружу выдавала указатели на А. И уже снаружи, вызывающая сторона приводила А к чему ей было нужно, ничего не зная о том, какой в действительности был сконструирован объект самой фабрикой. На мой взгляд, человек допустил этот архитектурный ляп потому что не осознавал как работает полиморфизм на низком уровне. А когда осознал всю неправильность своего творчества, было уже поздно - слишком многое было завязано на такой фабрике. И ему не оставалось ничего иного, кроме как воспользоваться услугами динамик_каст. Итого: неоправданное падение производительности там, где этого можно было с лёгкостью избежать. С другой стороны, архитектурные сооружения, которые вынуждают проектировщиков высокого уровня знать о том, как механизмы (наследования, полиморфизма) работают на низком уровне - это попахивает нарушением инкапсуляции. Лучше просто не связываться с такими архитектурными сооружениями следуя простому правилу: 1. Избегайте множественного наследования. 2. Избегайте глубокого наследования полиморфных интерфейсов. А вообще, в с++ действует одно железное правило "ружья и собственной ноги". Оно гласит: "Можно все! Если знаешь что делаешь. Если не знаешь - тогда нельзя"
0
|
||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||||||
| 24.11.2011, 10:43 | ||||||
|
Добавлено через 56 секунд
0
|
||||||
|
|
||
| 24.11.2011, 10:53 | ||
![]() Не надо нечего и никому избегать, и правила все эти нумерованные тоже никому не нужны... Просто всегда нужно знать, чего делаешь, и только-то; в этой теме уже предостаточно написано, чтоб разобраться и в приведении типов, и в dynamic_cast, и в наследовании, и в таблицах функций... правила эти ваши зачем?
0
|
||
|
Заблокирован
|
|||||||||
| 24.11.2011, 10:59 [ТС] | |||||||||
Добавлено через 2 минуты Работать с объектом по указателю == работать с самим объектом по значению. При этом, если тип указателя и тип объекта, который живет на самом деле по адресу - разные, что будит? Будит срезка, или ещё какие нибудь не очень приятные приколы Добавлено через 1 минуту
0
|
|||||||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|||
| 24.11.2011, 11:02 | |||
![]() Почему так происходит я уже разжевал и разложил по полочкам. То, что ты не желаешь читать - не мои проблемы. Когда надумаешь действительно разобраться в проблеме, то перейди на третью страницу. Добавлено через 2 минуты Ты даже не можешь толком разобраться в примере, ссылку на который привёл. Там объект передаётся по значению, поэтому там и есть срезка.
0
|
|||
|
Заблокирован
|
||
| 24.11.2011, 11:04 [ТС] | ||
|
По-моему, срезка - это когда большой объект приводится (интерпритируется) как более мелкий. И часть данных в итоге улетает в трубу. В данном случае, компилятор считает что по указанному адресу живет объект типа A Ну или объект типа B На самом деле там живет объект типа C, но при обращении к объекту через указатель, компилятор воспринимает объект не как С, а как А или B. Таким образом, объект, с которым происходит работа через левый указатель, оказывается срезанным.
0
|
||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||||||||
| 24.11.2011, 11:14 | ||||||||
|
Более того, невозможно изменять интерпретацию объектов. Интерпретировать можно лишь указатели. Что такое приведение объекта? Это вызов копирующего конструктора. Виртуальных конструкторов не бывает, поэтому при копировании(приведении типа) копируются не все данные. Это и есть срезка. О том, что такое срезка я уже писал выше, поэтому повторю Придумал, как объяснить нагляднее! Смотри, читай, задавай вопросы.
Специально для тебя Дьюхэрст написал книгу "Скользкие места C++". Глава по "срезке" на странице 77. Если и после этого просветление тебя не посетит, то прекращай использовать наследование в любых формах. Указателями лучше тоже кончай пользоваться.
0
|
||||||||
|
Заблокирован
|
|||||||
| 24.11.2011, 11:19 [ТС] | |||||||
Почему же тогда не запустился копирующий конструктор, а?? Как вы можете это объяснить? Или может быть все таки, вы не правы? А я вам объясню: объект это просто кучка байтов. Сама по себе не имеющая типа. О том, как интерпритируется эта кучка байтов знает либо тип переменной, либо тип указателя. И если тип указателя A, то компилятору пофегу, что на самом деле там живет C При работе с объектом через такой указатель, компилятор будит считать, что там живет А Это к вопросу об интерпретации данных. Привести один тип к другому, не значит скопировать данные. Это значит сказать компилятору: интерпретируй этот объект, как объект другого типа. При этом, при работе с "приведенным" типом так же может происходить срезка данных. Когда одни данные начинают восприниматься как другие данные, а часть данных вообще будит тупо проигнорирована. Срезка происходит не когда данные не полностью скопированы, а тогда, когда компилятор уже "потерял" часть объекта.
0
|
|||||||
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||
| 24.11.2011, 11:29 | ||
|
Интерпретация данных, это reinterpret_cast, вызвать для не скалярных типов нельзя. Приведение типов static_cast - создание копии. Интерпретация и приведение типа это не одно и то же. Если строка 21 отработает, то произойдёт срезка t.
0
|
||
| 24.11.2011, 11:29 | |
|
Xmega грабли Грабли с USART_FLAG_RXNE Наступлю на те же грабли?
Грабли malloc/free Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F
Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU.
Опрашиваются регистры. . .
|
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка:
Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
|
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо
Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
|
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман.
Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
|
|
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
|
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
|
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ
Основная суть и тезисы по измерениям:
0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема.
Объект не может перемещаться в 0D.
1D (Первое измерение):. . .
|
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek
ВВЕДЕНИЕ
Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
|