быдлокодер
![]() 1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,691
|
||||||
1 | ||||||
Как вызвать виртуальную функцию из дочернего класса, если она определена и вызывается в конструкторе РОДИТЕЛЬСКОГО класса?02.06.2011, 21:48. Показов 10797. Ответов 19
Метки нет Все метки)
(
Ну то есть так: есть родительский и дочерний класс, в родительском определен виртуальная функция и вызывается в его конструкторе (камень преткновения; и не вызывать нельзя). А есть дочерний класс и в нём эта вирутальная функция переопределена. Я создаю объект дочернего класса, он благополучно вызывает конструктор родительского класса и вызывается эта функция, но РОДИТЕЛЬСКИЙ вариант. А мне нужен ДОЧЕРНИЙ. Спасибо кто поможет. Может я где теорию упустил, не знаю.
0
|
02.06.2011, 21:48 | |
02.06.2011, 21:48 | |
Ответы с готовыми решениями:
19
Как вызвать функцию родительского класса? Как из метода производного класса вызвать поле родительского класса Как вызвать метод вложенного класса в методе родительского класса |
5 / 5 / 4
Регистрация: 05.12.2009
Сообщений: 13
|
||||||
03.06.2011, 00:00 | 2 | |||||
Попробуй обратиться к объекту производного класса через указатель
0
|
быдлокодер
![]() 1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,691
|
|||||||||||
03.06.2011, 01:20 [ТС] | 3 | ||||||||||
Не помогает, просто создаётся объект типа sin, соответственно вызывается конструктор родительского объекта, и f (), определённая в родительском же объекте. А мне надо чтобы та функция вызывалась, что переопределена в дочернем объекте.
Добавлено через 13 минут Решилось так: в конструктор дочернего класса я вставил вызов функции f, а из конструктора базового класса этот конструктор убрал.
0
|
![]() 594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
|
|
03.06.2011, 01:53 | 4 |
понял - ты хочешь вызывать из базового класса какую то версию функции объявленной в нем но переопределенной в производном ..
но ведь базовый класс не знает ни о каких других версиях этой функции ( у него своя таблица vtable в которой только адреса функций базового) -> не ясно как ты хочешь добиться такого эффекта. пс если получится отпишись
0
|
![]() 187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
|
||||||
03.06.2011, 07:39 | 5 | |||||
я так понял, что нужно в дочернем классе вызвать функцию родительского, которая была переопредела в нём. Если это так, то нужно просто явно указывать версию sin::f() - функция родительского класса, base::f() - функция дочернего. То есть наоборот блин. Тогда никаких неоднозначностей не будет
Добавлено через 4 часа 11 минут
2
|
101 / 88 / 7
Регистрация: 17.12.2010
Сообщений: 416
|
|
03.06.2011, 08:28 | 6 |
kravam, при создании объекта производного класса, сначала вызывается конструктор базового класса (со своей функцией void f() ), а потом конструктор производного класса(опять же со своей функцией void f() ). то есть конструктор базового класса (вместе со своими функциями) вызывается всегда, а вы хотите, что бы он не вызывался что ли?
0
|
![]() ![]() 3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
|
|
03.06.2011, 08:32 | 7 |
Дело в том, что виртуальность функции проявляется не всегда, а только в том случае, когда она вызывается через ссылку или указатель на базовый класс. Во всех остальных случаях функция воспринимается компилятором как невиртуальная.
0
|
5 / 5 / 4
Регистрация: 05.12.2009
Сообщений: 13
|
|
03.06.2011, 13:22 | 8 |
немного пораздумав, прихожу к выводу, что возможности обратиться к методу производного класса быть не может. как и в принципе вызова переопределенной виртуальной функции из конструктора.
в момент, когда конструктор базового класса вызывает функцию f(), объект производного класса еще не создан и, соответственно, его метод вызван быть не может. кстати, если бы у виртуальной функции базового класса не было бы тела, наверняка появилась бы ошибка типа "access violation"
0
|
![]() ![]() ![]() |
|
03.06.2011, 15:18 | 9 |
Я не специалист по Си++, но мне тоже кажется, что так оно и есть. Конструктор вызывается для инициализации собственных полей, а потому конструктор может вызывать только методы, определённые в данном классе (или у родителей). Логично, что работать с виртуальными методами можно только после того, как объект уже создан, а в процессе работы конструктора объект как бы ещё не до конца создан
0
|
![]() 187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
|
|
03.06.2011, 15:25 | 10 |
внутри конструктора производного класса можно работать с методами базового класса и вызывать любые свои методы
0
|
![]() |
||||||
03.06.2011, 16:40 | 11 | |||||
Evg, по-моему первым делом создается таблица виртуальных ф-ций и VPTR (указатель на эту таблицу) инициализируется первым делом при входе в конструктор (на MSVS VPTR имеет смещение 0, относительно объекта), а значит в конструкторе уже можно использовать виртуальные ф-ции. Другое дело, что надеется на это не стоит, т.к. в стандарте это не прописанно, а значит не факт, что какой-нибудь компилятор не сделает по другому.
Но вот такой код работает (пришлось изменить имя класса с sin на sinn, иначе студия негодовала)
1
|
![]() 187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
|
|
03.06.2011, 16:51 | 12 |
есть такая книга. Оформлена так, что главы там называются "советы" и в ней очень много написано как раз про то как работают все эти касты с наследоваными классами. Может кто вспомнит автора\название?
0
|
![]() ![]() ![]() |
|
03.06.2011, 16:54 | 13 |
Я говорил не о том, как оно технически реализовано, а том, как оно идиологически должно быть устроено. При работе с виртуальными классами должна быть как минимум одна точка, где известен тип объекта - это его создание (ну и, соотвественно, конструктор). При этом базовый клас вообще ничего не должен знать о производных классах (ибо в противном случае это вообще не ООП, что имееет место быть в твоём примере из поста #11)
0
|
бжни
![]() 2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
|
|
03.06.2011, 17:05 | 14 |
0
|
Kastaneda
|
03.06.2011, 17:09
#15
|
1
|
![]() ![]() 3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
|
|
03.06.2011, 17:09 | 16 |
На самом деле по стандарту виртуальныные функции, вызываемые в конструкторе или деструкторе, принадлежат к тому же классу, что и конструктор или деструктор. Если было бы иначе, то, как уже замечено выше, это было бы нарушением инкапсуляции.
1
|
быдлокодер
![]() 1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,691
|
||||||
03.06.2011, 17:18 [ТС] | 17 | |||||
Kastaneda, а Вы не могли бы пояснить, в Вашем коде мне худо-бедно понятно всё. Ну то есть создаётся производный класс (сперва базовый и указатель на него переопределяется в указатель на производный (который типа есть ну или вот-вот будет) и вызывается функция производного класса)
Это понятно. Но как может вызываться функция объекта, которого не то что нет, а и быть не может? Напишем в вашем коде так:
Как это понимать? Я вообще теряюсь.
0
|
![]() |
|
03.06.2011, 17:33 | 19 |
Ты
Этот код просто для примера, в данном конкретном случае он работает, но, что будет, если создать объект базового класса - неизвестно (студия вывела сообщение из sin::f(), ибо темные силы движут ей))). Так делать вообще нельзя, о чем уже было написанно выше. Добавлено через 5 минут Не по теме:
0
|
![]() 594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
|
|
03.06.2011, 17:58 | 20 |
А если у нас много производных классов и для каждого нужно вызывать свою функцию?
я не понял вообще как это происходит. (наверное потому что код не завязан на переменных а просто выводит сообщение поэтому и нет ошибок) самое смешное что если заменить reinterpret_cast на менее брутальное static_cast всё равно работает
0
|
03.06.2011, 17:58 | |
03.06.2011, 17:58 | |
Помогаю со студенческими работами здесь
20
Обращение к методу дочернего класса из экземпляра родительского класса В конструкторе вложенного класса инициализируется приватное поле. Потом вызывается функция-метод этого класса и выводит значение этого поля НО НЕ ТО!
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
![]() |
Опции темы | |
|
Новые блоги и статьи
![]() |
||||
Создаем SPA Router на чистом JavaScript
bytestream 17.02.2025
В современной веб-разработке одностраничные приложения (SPA) стали стандартом для создания динамичных и отзывчивых пользовательских интерфейсов. Ключевым компонентом любого SPA является роутер -. . .
|
Машинное обучение на TypeScript и TensorFlow
bytestream 17.02.2025
Машинное обучение становится все более востребованным направлением в современной разработке программного обеспечения. Интеграция искусственного интеллекта в веб-приложения открывает новые возможности. . .
|
Манипуляция данными EXIF и JPEG в JavaScript
bytestream 17.02.2025
В современном мире цифровой фотографии метаданные изображений играют важнейшую роль в организации и управлении медиаконтентом. Формат EXIF (Exchangeable Image File Format) - это стандарт,. . .
|
Как создать GUID/UUID в JavaScript
bytestream 17.02.2025
GUID (Globally Unique Identifier) и UUID (Universally Unique Identifier) - это специальные форматы 128-битных идентификаторов, которые практически гарантируют уникальность значения во времени и. . .
|
Что такое мышление в упрощенном смысле (моё субъективное видение, для создания модели).
Hrethgir 17.02.2025
Разумеется упрощать смысл есть. Дело в том, что я пришёл к тому выводу, что даже если я создам свой процессор (конвейер), то первое для чего смогу его использовать в качестве демонстративного. . .
|
Как Node.js устроен изнутри
Wired 17.02.2025
Node. js коренным образом изменил подход к веб-разработке, позволив использовать JavaScript не только в браузере, но и на стороне сервера. Созданный в 2009 году Райаном Далем, Node. js представляет. . .
|
Как обновить Node.js в Windows
Wired 17.02.2025
Думаю, многие разработчики сталкивались с ситуацией, когда устаревшая версия Node. js становилась источником проблем - от несовместимости с новыми пакетами до уязвимостей в безопасности. Особенно это. . .
|
Как обновить Node.js в MacOS
Wired 17.02.2025
В Node. js существует несколько подходов к обновлению, каждый из которых имеет свои преимущества и особенности применения. Выбор конкретного метода зависит от ваших потребностей - будь то. . .
|
Как обновить Node.js в Linux
Wired 17.02.2025
Обновление Node. js может показаться сложной задачей, особенно если у вас несколько проектов с разными зависимостями. Однако существует несколько надежных способов обновления, подходящих для разных. . .
|
[golang] 134. Gas Station
alhaos 17.02.2025
Тут нам даны два целочисленных слайса gas и cost, индексы массива представляют собой заправочные станции. а элементы gas это количество топлива на такой станции, cost это количество топлива. . .
|