Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826

Принудительный вызов метода родителя

04.07.2015, 03:54. Показов 3816. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
using namespace std;
class A
{
public:
    virtual void f()
    {
        cout << "A::F()" << endl;
    }
    virtual void onLoad()
    {
        cout << "A::onload()" << endl;
        f(); // если бы метод f не был бы виртуальным данная запись была бы эквивалентна реализационой компилятором 
        // записи A::f(this) или для внешнего вызова a.f();  --> A::f(&a);
        // но так как метод f виртуальный - его вызов определяется в момент конкретного вызова на этапе выполнения
        // через указатель в каждом экземпляре __vfptr.
        // Следовательно запись this->__vfptr->f(this); 
 
        this->A::f(); // Данная же запись отбрасывает вызов метода f() через таблицу виртуальных функций.
        // И так как для метода A::f() входным параметром является const A* this , то вызывая метод в 
        // производном классе onLoad - метод базового, иы передаем туда указатель A*.
 
        // Следовательно - верно ли утверждение, что при явном указании класса от которого нужно вызввать виртуальный
        // метод, вызов метода через виртуальную таблицу функций не используется.
 
        // И это вопрос на другую тему: если я правильно понимаю, при виртуальном наследовании класса в ромбовидной иерархии
        // к примеру, каждый экземпляр наследников хранит 4 байта информации, что предоставляет собой смещение - тоесть
        // разницу адрессов между адрессов экземпляра виртуального родителя и адрессом экземпляра наследника. Данные 4 байта
        // скрыты в дебаге от глаз, так как их использована чревато и используется лишь компилятором для организации работы с классом 
 
        
    }
};
class B : public A
{
    typedef A Parent;
public:
    virtual void f()
    {
        cout << "B::F()" << endl;
    }
    virtual void onLoad()
    {
        A::onLoad();
        cout << "B::onload()" << endl;
        f();
    }
};
int main()
{
    B b;
    b.onLoad();
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.07.2015, 03:54
Ответы с готовыми решениями:

Вызов метода родителя
Добрый вечер, как можно заставить метод &quot;не забыть&quot; вызвать этот же метод родителя ? Есть такая &quot;очень классная...

Вызов метода потомка через указатель на родителя
Всем доброго времени суток, никак не придумаю, как провернуть такое: Пишу простенькую игру на cocos2dx. Есть первый класс, CNode - он...

Наследование. Переопределение метода родителя
не работает конструкция вида: class AllFigureData { protected: int id; int x; int y; public: virtual void getdata(); };

15
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.07.2015, 07:01
Лучший ответ Сообщение было отмечено rikimaru2013 как решение

Решение

1. Да - вызовы f() и this->A::f() реализованы по-разному. Вот асм выхлоп
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
; вызов через VPTR
    movq    -8(%rbp), %rax ; получаем адрес объекта
    movq    (%rax), %rax ; получаем адрес таблицы вирт. ф-ций
    movq    (%rax), %rax ; получаем адрес ф-ции f()
    movq    -8(%rbp), %rdx
    movq    %rdx, %rdi
    call    *%rax ; вызываем f()
 
; а это простой вызов
    movq    -8(%rbp), %rax ; получили адрес объекта
    movq    %rax, %rdi 
    call    _ZN1A1fEv ; и напрямую вызываем A::f
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
// Следовательно - верно ли утверждение, что при явном указании класса от которого нужно вызввать виртуальный
* * * * // метод, вызов метода через виртуальную таблицу функций не используется.
да

2. Внутреняя реализация виртуального наследования не описана в стандарте (как и реализация виртуальных вызовов). Просто чаще всего компиляторы делают это так, как мы привыкли считать. В общем случае где-то будет храниться смещение, про которое ты пишешь.
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.07.2015, 12:32
Лучший ответ Сообщение было отмечено rikimaru2013 как решение

Решение

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
верно ли утверждение, что при явном указании класса от которого нужно вызввать виртуальный метод, вызов метода через виртуальную таблицу функций не используется.
верно.

про виртуальное наследование:
мне не удалось распарсить ваш поток сознания.

если вкратце: при виртуальном наследовании,
компилятор задействует динамический полиморфизм,
обрабатывая вызовы функций:

C++
1
obj->method();
так, словно это был вызов через указатель:
C++
1
obj->pBase->method();
где кусочек:
C++
1
pBase->method();
можно рассматривать,
как классический случай полиморфизма на языке с++

вот здесь есть наглядное и доступное описание низкоуровневой механики на русском языке:
http://devdoc.web-ide.ru/index... itance.htm
1
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.07.2015, 13:11
Цитата Сообщение от hoggy Посмотреть сообщение
если вкратце: при виртуальном наследовании,
компилятор задействует динамический полиморфизм,
обрабатывая вызовы функций:
Теперь я не понял, о чем речь?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.07.2015, 13:14
Цитата Сообщение от Kastaneda Посмотреть сообщение
Теперь я не понял, о чем речь?
неудивительно.
что бы распарсить такое "вкратце",
нужно изначально понимать механику вирт. наследования.

я оставил ссылку, там все популярно (с картинками) разъясняется.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.07.2015, 13:47
Цитата Сообщение от hoggy Посмотреть сообщение
нужно изначально понимать механику вирт. наследования.
Это я как раз понимаю. Непонятно другое
Цитата Сообщение от hoggy Посмотреть сообщение
при виртуальном наследовании,
компилятор задействует динамический полиморфизм,
А при обычном наследовании? Что значит "компилятор задействует динамический полиморфизм"?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.07.2015, 14:17
Цитата Сообщение от Kastaneda Посмотреть сообщение
А при обычном наследовании?
нет.

Не по теме:

странный вопрос, учитывая ваше заявление,
что вы понимаете, как работает вирт. наследование.



Цитата Сообщение от Kastaneda Посмотреть сообщение
Что значит "компилятор задействует динамический полиморфизм"?
вы знаете, что такое "динамический полиморфизм"?

есть статический, есть динамический.

в основе динамического лежит механика виртуальных функций.
вот эту механику он и задействует.

по ссылке, что я оставил,
если покапаться, можно найти статью:
"виртуальные функции, низкоуровневый взгляд".

подробности вы можете узнать там.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.07.2015, 14:38
Просто вот это
Цитата Сообщение от hoggy Посмотреть сообщение
при виртуальном наследовании,
компилятор задействует динамический полиморфизм,
обрабатывая вызовы функций
не совсем корректно, потому я собственно и прицепился. Что меняется в вызове ф-ций при виртуальном наследовании? Ничего. При использовании виртуальных функций компилятор использует позднее связывание, если ф-ции не виртуальны - используется раннее связывание. Это поведение не зависит от типа наследования.
0
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
04.07.2015, 15:14
Чем меньше наследования и виртуальных функций в коде, тем лучше

Кому-нибудь вообще пригодилось знание механизма вызова виртуальных функций? Мне например только на давних собеседованиях, на которых этим вопросом скорее просто проверяли, а читал ли чел вообще что-нибудь по С++ В реальном коде потребность реализовывать свою VMT, понимать хитровывернутые последовательности вызова функций, обращать пристальное внимание на размер объектов, практически нигде не требуется.
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
04.07.2015, 15:31  [ТС]
Цитата Сообщение от ct0r Посмотреть сообщение
Кому-нибудь вообще пригодилось знание механизма вызова виртуальных функций?
Я с вами не согласен. Если взять поваров: то они работают с ингредиентами и соусами. И лучшим является тот, кто знает как с рыбы взять филе, а еще лучшим тот кто знает чем отличается южный окунь от северного окуня (утрирую). Но разве не так?
0
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
04.07.2015, 16:20
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Я с вами не согласен. Если взять поваров: то они работают с ингредиентами и соусами. И лучшим является тот, кто знает как с рыбы взять филе, а еще лучшим тот кто знает чем отличается южный окунь от северного окуня (утрирую). Но разве не так?
Лучшим является тот, кто лучше готовит. Остальное - понты. Вообще вопрос относился к тому, пригодилось ли кому это знание и каким образом. Про нужность или ненужность чего-либо речи не было.
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
04.07.2015, 17:54
Цитата Сообщение от ct0r Посмотреть сообщение
Кому-нибудь вообще пригодилось знание механизма вызова виртуальных функций?
Так он вроде бы не стандартизован и от реализации зависит. Какой смысл его знать-то?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.07.2015, 18:42
Цитата Сообщение от Kastaneda Посмотреть сообщение
не совсем корректно
предлагаю вам проиллюстрировать ваше виденье.

Цитата Сообщение от ct0r Посмотреть сообщение
Кому-нибудь вообще пригодилось знание механизма вызова виртуальных функций?
да.

Цитата Сообщение от Mr.X Посмотреть сообщение
Так он вроде бы не стандартизован и от реализации зависит.
не путайте использование, и реализацию (технологии компиляторов)

использование стандартизировано.
а сама механика - unspecified.
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
04.07.2015, 19:26
Цитата Сообщение от hoggy Посмотреть сообщение
не путайте использование, и реализацию (технологии компиляторов)
Не, это вы нас не путайте. Тут все именно про реализацию и рассуждают.

Добавлено через 38 минут
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
// И это вопрос на другую тему: если я правильно понимаю, при виртуальном наследовании класса в ромбовидной иерархии // к примеру, каждый экземпляр наследников хранит 4 байта информации, что предоставляет собой смещение - тоесть // разницу адрессов между адрессов экземпляра виртуального родителя и адрессом экземпляра наследника. Данные 4 байта // скрыты в дебаге от глаз, так как их использована чревато и используется лишь компилятором для организации работы с классом
Здесь вы перепутали малость. Во-первых, при ромбовидном множественном наследовании (невиртуальном) наоборот объект-потомок содержит несколько подобъектов базового класса. А, во-вторых, именно при виртуальном ромбовидном наследовании подобъект базового класса всего один.
1
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
04.07.2015, 20:32
Цитата Сообщение от hoggy Посмотреть сообщение
да.
Каким образом? Какую проблему это знание помогло решить?

Цитата Сообщение от Mr.X Посмотреть сообщение
Так он вроде бы не стандартизован и от реализации зависит. Какой смысл его знать-то?
Ну само собой. Но вопрос не совсем ко мне - я уже говорил, что у меня только на собеседованиях смысл был.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.07.2015, 21:47
Цитата Сообщение от ct0r Посмотреть сообщение
Каким образом? Какую проблему это знание помогло решить?
изготовление делегатов
(вызов функции/функции-члена).

пачка тестов, потому что здесь и сейчас работает...


зато быстро

и потом, такое на собеседовании спрашивают,
что бы отфильтровать программиста от обезъянки.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.07.2015, 21:47
Помогаю со студенческими работами здесь

Вызов из потомка конструктор родителя
Как на с++ вызывается конструктор-родителя от конструктора-потомка. На яве так работает: package u; class A{ private int a,b,c;...

Вызов метода объекта внутри определения метода другого объекта(вложенные классы)
Как мне вызвать метод объекта slider класса Slider внутри определения метода объекта класса StateBar? class StateBar { public: ...

Вызов метода из метода
Можно ли вызвать метод из метода. Это программа не работает #include&lt;iostream&gt; using namespace std; class a {private: int b,c,d;...

Вызов метода
Друзья подскажите пожалуйста! Есть родительский класс TModel, в нем есть метод Euler2(), как это метод вызвать в дочернем классе...

Вызов метода
Добрый вечер, я не знаю c++, пытаюсь разобраться, знаком с c#, delphi. Создаю библиотеку для c# проекта. Как вызвать метод? ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru