47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
|
|||||||||||
1 | |||||||||||
Неявное приведение указателей на классы05.04.2016, 10:28. Показов 3010. Ответов 15
Метки нет (Все метки)
Всем привет!
Обнаружилась вот такая нестыковочка: имеем интерфейсный класс IIn. И имеем класс-наследник ExtIn : public IIn далее имеем такой код:
Это где-то в стандарте описано или это какая-то особенность языка, о которой я еще не знаю? Как такое поведение компилятора вообще объяснить?
0
|
05.04.2016, 10:28 | |
Ответы с готовыми решениями:
15
Запретить неявное приведение Неявное приведение типов Запретить неявное приведение возвращаемого значения Приведение указателей |
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
|
|
05.04.2016, 10:32 [ТС] | 3 |
Вопрос внизу:
Подскажите, чем обусловлена данная ситуация с двойными указателями? Это где-то в стандарте описано или это какая-то особенность языка, о которой я еще не знаю? Как такое поведение компилятора вообще объяснить? Почему компилятор отказывается конвертировать двойные указатели без пинка?
0
|
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
|
|
05.04.2016, 10:50 [ТС] | 5 |
Спасибо.
Жаль, что такой могучий язык не может рекурсивно распарсить такую несложную конструкцию до начальных объектов... и сделать конвертацию самостоятельно... Не зря я когда-то любил макроассемблер... Любовь к нему все еще тлеет во мне... )))
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
05.04.2016, 12:42 | 6 |
Как вы себе это представляете? Учитывая, что
(void*)pABCD!=(void*)p_2_ABCD. На какую область памяти по вашему должен указывать pp_3_ABCD?
0
|
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
|
|
05.04.2016, 13:48 [ТС] | 7 |
А вот взаимное расположение подобъектов базового и производного классов уже зависит от конкретной реализации компилятора. Так что если очень захотеть.. можно в космос полететь.
А вообще, обычно новые поля расположены в памяти за полями предка. Исключение составляет виртуальное наследование. Поля виртуальных классов обычно располагают в самом конце. Сейчас проверил в своем компиляторе - указатели равны. Да и вопрос не в равенстве, а в правильном конвертировании. Добавлено через 5 минут А еще при участии классов с виртуальными функциями в наследовании приоритет при размещении имеют именно они. Опять-таки в конкретном компиляторе
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||||||
05.04.2016, 14:04 | 8 | |||||
И что? Если базовых классов несколько? В общем они не равны.
Похоже вы не понимаете как работают указатели. Пусть есть класс Foo. Пусть есть переменная Foo **********foo; Тогда вызвать ее метод можно так: (**********foo).bar()Каждая звездочка - обращение по какому-то адресу в памяти в котором содержится следующий адрес. Информации о типах указателей во время выполнения нет. Как вы собрались отличать, какая ячейка памяти на что указывает? Вот есть ячейка памяти (соответствует цепочке указателей начинающейся красным). К какому смещению она приведет? Класса или его предка? Добавлено через 7 минут чтобы сделать так:
1
|
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
|
|
05.04.2016, 17:08 [ТС] | 9 |
Не надо мне приписывать те заслуги, которых у меня нет.
А как ВЫ отличаете во время выполнения, на что указывает указатель? О том, что это указатель, и на что он указывает, знает только компилятор. А как это происходит в случае одинарного указателя? Эта ячейка приведет к данным, общим, как для предка, так и для наследника. Поэтому можете смело к ним обращаться. И именно от того, что эти данные одинаковы для базы и для наследника, а у наследника свой, дополнительный, набор данных возможна неявное преобразование указателя на наследника в указатель на предка. Но не наоборот. Не вижу вообще проблемы сделать преобразование для множественного указания по аналогии с одиночным.
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||||||
05.04.2016, 17:28 | 10 | |||||
Видимо есть заслуги
0
|
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
|
|
05.04.2016, 19:06 [ТС] | 11 |
Не вижу смысла дальше продолжать спор - Вы слишком брызжете слюной доказывая свою правоту.
Можете считать, что Вы правы.
0
|
18898 / 9856 / 2410
Регистрация: 30.01.2014
Сообщений: 17,299
|
||||||
05.04.2016, 19:43 | 12 | |||||
Но ведь он на самом деле прав
Вот небольшой примерчик. Первая попытка - это правильное приведение (исходим из того, что в общем случае адреса наследника и базы не равны, что подтверждают как в общем правила C++, так и конкретный пример в частности), поэтому нам нужна временная переменная-указатель. Вторая попытка - это неверный каст, который исходит из предпосылок, что адреса равны. В итоге, во втором случае получаем закономерный некорректный результат.
С++ не может разрешить такое приведение через уровни по-умолчанию, т.к. в общем случае нам понадобиться временная переменная, чтобы хранить промежуточный адрес. И чем больше уровней указателя, тем больше таких переменных понадобится. Но проблема даже не в их наличии, а в том, что в общем виде нельзя решить задачу определения времени жизни этих переменных. Не по теме: PS. Это мой первый и последний пост в этой теме.
0
|
Вездепух
11696 / 6375 / 1724
Регистрация: 18.10.2014
Сообщений: 16,078
|
||||||
05.04.2016, 22:22 | 13 | |||||
Сообщение было отмечено Pink_Pank как решение
Решение
Этот вопрос возникает часто в разных проявлениях. В частности, другая реинкарнация этой же темы - часто задаваемый вопрос о том, почему указатель
int * можно неявно привести к const int * , а вот int ** к const int ** сам приводиться не хочет. "Ведь должно же тоже приводиться!".На самом деле, дыра в логике вопрошающего тут точно такая же, как была бы вот в таком случае: тип int можно неявно привести к типу double , но это совсем на значит, что указатель int * можно неявно привести к указателю double * . Вот это последнее "несоответствие" почему-то никого не удивляет. Хотя на самом деле фундаментальная проблема с неявным приведением int * к double * - точно такая же, и как с неявным приведением int ** к const int ** , и как с вашей попыткой привести ExtIn ** к IIn ** .Например, если бы приведение ExtIn ** к IIn ** было разрешено, мы бы могли сделать вот такой "финт ушами"
p_ext_in типа ExtIn * указывает на совершенно посторонний объект ya_vasya совершенно постороннего типа VasyaPupkin . И для того, чтобы вот так "сломать" систему типов языка вам не понадобилось сделать ни одного насильного приведения типов (!).Это лишь иллюстративный пример. Ваше предположение, что из конвертируемости ExtIn * к IIn * должна следовать конвертируемость ExtIn ** к IIn ** - бессмысленно и безосновательно. Этот пример лишь иллюстрирует одно из очевидных проявлений этой бессмысленности.Вам выше наприводили других примеров, также иллюстрирующих эту бессмысленность.
1
|
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
|
|
05.04.2016, 22:35 [ТС] | 14 |
DrOffset, В общем-то, Ваш пример никак не противоречит сказанному мною. Переменная требуется всего одна. Независимо от уровней. Требуется она для промежуточных вычислений. И время жизни ее может быть сколь угодно мало. Вы же не задумываетесь о времени жизни значений в регистрах процессора, которые компилятор использует для хранения промежуточных значений.
Добавлено через 11 минут TheCalligrapher, спасибо! Вот Ваш пример действительно оказался иллюстративным. ) замазали дыру. С Вами уже трудно не согласиться. )
0
|
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||||||
06.04.2016, 00:51 | 15 | |||||
Вы сильно заблуждаетесь. Cколько звездочек - столько требуется и переменных. Вам уже 2 раза об этом сказали.
0
|
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
|
|
06.04.2016, 09:07 [ТС] | 16 |
Естесственно, что для хранения всех этих промежуточных адресов требуется отдельные ячейки памяти. И время жизни их зависит от того, как Вы эти ячейки и где объявите.
Я просто не понял, что Вы хотите сказать. Я подумал, что помимо участков памяти под указатели Вы хотите выделить кучу еще каких-то..
0
|
06.04.2016, 09:07 | |
06.04.2016, 09:07 | |
Помогаю со студенческими работами здесь
16
Приведение указателей Приведение указателей в стиле си приведение типов указателей Отличие приведение типов указателей Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |