|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
13.11.2009, 22:30 | #1 |
Пользователь
Регистрация: 08.11.2009
Сообщений: 16
|
ООП. Обращение к вирт. функциями в вирт. классах
Привет.
Приобретаю навыки ООП С++ и встала такая ошибка - привидение показывает не правильный результат (см. ниже) Листинг 1: Код:
x1= -1163005939 x2= -1163005939 a1= -1163005939 a2= -1163005939 b1= -1163005939 b2= -1163005939 c1= 50 c2= 50 Когда я писал такое наследование (ниже), то привидение к типу объекта было корректным... Листинг 2: Код:
Последний раз редактировалось MasterGH; 13.11.2009 в 22:37. |
13.11.2009, 23:13 | #2 |
Старожил
Регистрация: 22.05.2007
Сообщений: 9,065
|
Дело в том, что это не приведение типа. Приведение типов записывается так:
(тип) переменная. В данном случае надо: (Vabstract) (*obj3). А еще лучше использовать родные приведения типов языка С++: static_cast<тип>(переменная), dynamic_cast<тип>(переменная),... А запись Vabstract(*obj3) - это конструирование нового экземпляра типа Vabstract посредством вызова конструктора копии. Получается, что функция set вызывается для одних временных объектов, а getInfo - для совершенно иных, потому на экран и выходит мусор. |
14.11.2009, 00:14 | #3 | ||||
Пользователь
Регистрация: 08.11.2009
Сообщений: 16
|
Цитата:
(Vabstract)(*obj3).set(1000,1000); Мне выдаёт ошибку: Цитата:
Цитата:
Цитата:
Спасибо. В общем полез я опять в отладчик к таблицам виртуальных функций буду следить за регистрами к какой виртуальной таблице происходит обращение. А после буду читать про cast-ы. А вообще не хотелось бы использовать dynamic_cast и собирать, наверно, лишнюю информацию об RTTI ... |
||||
14.11.2009, 00:50 | #4 | |
Старожил
Регистрация: 22.05.2007
Сообщений: 9,065
|
Цитата:
Типы приводить нужно через указатели. В си-стиле это: Код:
Код:
Код:
В качестве теста можно в private/protected часть засунуть реализацию конструктора: Vabstract(Vabstract const &) {}, чтобы компилятор сам её в public'e не создавал и не копировал что не надо. С таким конструктором static_cast<Vabstract> уже не сработает |
|
14.11.2009, 00:51 | #5 |
Участник клуба
Регистрация: 15.07.2008
Сообщений: 1,933
|
Опоздал =)
|
14.11.2009, 17:11 | #6 |
Пользователь
Регистрация: 08.11.2009
Сообщений: 16
|
Я немного переписал программу.. результат тот же - выводится мусор
Код:
x1= -1163005939 x2= -1163005939 a1= -1163005939 a2= -1163005939 b1= -1163005939 b2= -1163005939 c1= 30 c2= 30 Последний раз редактировалось MasterGH; 14.11.2009 в 17:15. |
14.11.2009, 17:27 | #7 |
Участник клуба
Регистрация: 15.07.2008
Сообщений: 1,933
|
Ф-ции ведь виртуальны, а объект был создан типа C, потому все ф-ции set будут вызваны именно для него и инициализированы будут только c1, c2, в остальных останется мусор
|
14.11.2009, 19:55 | #8 |
Пользователь
Регистрация: 08.11.2009
Сообщений: 16
|
netrino, я объяснение не понял.
Проблема как заставить работать виртуальные функции принадлежащие к тому или иному классу внутри иерархии классов, где присутствует виртуальное наследование базового класса в моём последнем примере? |
14.11.2009, 20:25 | #9 |
Участник клуба
Регистрация: 15.07.2008
Сообщений: 1,933
|
Суть виртуальных функций состоит в том, чтобы при приведении к базовому классу можно было вызывать методы производного. Например абстрактный класс поток, в котором есть виртуальная функция get, которая берёт 1 байт из потока, производными от этого потока будут, например, файловый поток, строковый поток и сетевой поток. Но так как get виртуальна, я могу написать ф-цию, которая читает строку из потока, при этом объявив, что в качестве параметра она принимает базовый поток, а передавать в неё любой из производных, при этом, в зависимости от полученного потока ф-ция прочитает строку из файла, строки или из сети.
Код:
|
15.11.2009, 01:54 | #10 |
Пользователь
Регистрация: 08.11.2009
Сообщений: 16
|
Нет, мне нельзя убирать ключевое слово virual, так не сформируется vftable объекта obj.
Я Вам помогу понять мою задачу. Я пишу безвозмездно статью о том, как формируются объекты в памяти (процесса игр) при сложных вариациях иерархий наследования и о том, как можно понять иерархию классов по псевдокоду плагина-декомпилятора Hex Rays из IDA. В данный момент меня интересует, как построятся данные таблицы vftable и vbtable объекта obj, а также структуры данных объекта obj, описание которого я привёл выше... только я не научился корректно вызывать виртуальные функции, т.к. не работал с С++, а только с Дельфи. Не то чтобы "работал", это моё хобби. Спасибо за пример, показывающий роль виртуальных функций. Я понимаю, что виртуальные функции нужны в работе как минимум с двумя объектами за счёт чего достигает полиморфизм – одна функция и разные объекты. Я не стал описывать классы других объектов, поэтому полиморфизма явно не видно. Считайте так, что каждая функция set оказалась виртуальной (т.к. существуют другие классы, за счёт которых происходит явление полиморфизма) и считайте что функция set должна работать с данными, описанными в том же классе что и виртуальная функция set. Спасибо за интерес к моей непростой теме =) |
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Помощь в классах и функциях. | Serror | Общие вопросы C/C++ | 11 | 10.10.2009 06:23 |
Паскаль ООП. Примеры программ с использованием ООП | SeЯgey | Помощь студентам | 5 | 13.05.2009 21:55 |
Небольшой этический вопросик о классах. | Longedok | Помощь студентам | 2 | 04.08.2008 13:23 |
реализация стратегии на классах | mahsus | Общие вопросы C/C++ | 1 | 28.12.2007 10:27 |