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

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

04.07.2015, 03:54. Показов 3855. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Вывод данных через динамический список в справочнике
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru