быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
|
||||||
1 | ||||||
Как вызвать виртуальную функцию из дочернего класса, если она определена и вызывается в конструкторе РОДИТЕЛЬСКОГО класса?02.06.2011, 21:48. Показов 10200. Ответов 19
Метки нет (Все метки)
Ну то есть так: есть родительский и дочерний класс, в родительском определен виртуальная функция и вызывается в его конструкторе (камень преткновения; и не вызывать нельзя). А есть дочерний класс и в нём эта вирутальная функция переопределена. Я создаю объект дочернего класса, он благополучно вызывает конструктор родительского класса и вызывается эта функция, но РОДИТЕЛЬСКИЙ вариант. А мне нужен ДОЧЕРНИЙ. Спасибо кто поможет. Может я где теорию упустил, не знаю.
0
|
02.06.2011, 21:48 | |
Ответы с готовыми решениями:
19
Как вызвать функцию родительского класса? Как из метода производного класса вызвать поле родительского класса Как вызвать метод вложенного класса в методе родительского класса Может ли метод родительского класса обратиться к полю дочернего класса |
4 / 4 / 4
Регистрация: 05.12.2009
Сообщений: 13
|
||||||
03.06.2011, 00:00 | 2 | |||||
Попробуй обратиться к объекту производного класса через указатель
0
|
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
|
|||||||||||
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
|
4 / 4 / 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,679
|
||||||
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
Обращение к методу дочернего класса из экземпляра родительского класса В конструкторе вложенного класса инициализируется приватное поле. Потом вызывается функция-метод этого класса и выводит значение этого поля НО НЕ ТО! Как вызвать метод родительского класса; Ссылка на метод дочернего класса из родительского Доступ к полям дочернего класса из родительского Как вызвать метод дочернего класса при приведении типов? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |