Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
rikimaru2013
C++ Game Dev
 Аватар для rikimaru2013
2137 / 970 / 223
Регистрация: 30.11.2013
Сообщений: 3,240
04.07.2015, 03:54     Принудительный вызов метода родителя #1
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();
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.07.2015, 03:54     Принудительный вызов метода родителя
Посмотрите здесь:

C++ Вызов из потомка конструктор родителя
Вызов метода из метода C++
C++ Вызов метода класса
C++ Вызов метода
Вызов метода в классе из другого C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
04.07.2015, 07:01     Принудительный вызов метода родителя #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
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. Внутреняя реализация виртуального наследования не описана в стандарте (как и реализация виртуальных вызовов). Просто чаще всего компиляторы делают это так, как мы привыкли считать. В общем случае где-то будет храниться смещение, про которое ты пишешь.
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
04.07.2015, 12:32     Принудительный вызов метода родителя #3
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
верно ли утверждение, что при явном указании класса от которого нужно вызввать виртуальный метод, вызов метода через виртуальную таблицу функций не используется.
верно.

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

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

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

вот здесь есть наглядное и доступное описание низкоуровневой механики на русском языке:
http://devdoc.web-ide.ru/index.php/c...nheritance.htm
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
04.07.2015, 13:11     Принудительный вызов метода родителя #4
Цитата Сообщение от hoggy Посмотреть сообщение
если вкратце: при виртуальном наследовании,
компилятор задействует динамический полиморфизм,
обрабатывая вызовы функций:
Теперь я не понял, о чем речь?
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
04.07.2015, 13:14     Принудительный вызов метода родителя #5
Цитата Сообщение от Kastaneda Посмотреть сообщение
Теперь я не понял, о чем речь?
неудивительно.
что бы распарсить такое "вкратце",
нужно изначально понимать механику вирт. наследования.

я оставил ссылку, там все популярно (с картинками) разъясняется.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
04.07.2015, 13:47     Принудительный вызов метода родителя #6
Цитата Сообщение от hoggy Посмотреть сообщение
нужно изначально понимать механику вирт. наследования.
Это я как раз понимаю. Непонятно другое
Цитата Сообщение от hoggy Посмотреть сообщение
при виртуальном наследовании,
компилятор задействует динамический полиморфизм,
А при обычном наследовании? Что значит "компилятор задействует динамический полиморфизм"?
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
04.07.2015, 14:17     Принудительный вызов метода родителя #7
Цитата Сообщение от Kastaneda Посмотреть сообщение
А при обычном наследовании?
нет.

Не по теме:

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



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

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

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

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

подробности вы можете узнать там.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
04.07.2015, 14:38     Принудительный вызов метода родителя #8
Просто вот это
Цитата Сообщение от hoggy Посмотреть сообщение
при виртуальном наследовании,
компилятор задействует динамический полиморфизм,
обрабатывая вызовы функций
не совсем корректно, потому я собственно и прицепился. Что меняется в вызове ф-ций при виртуальном наследовании? Ничего. При использовании виртуальных функций компилятор использует позднее связывание, если ф-ции не виртуальны - используется раннее связывание. Это поведение не зависит от типа наследования.
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
04.07.2015, 15:14     Принудительный вызов метода родителя #9
Чем меньше наследования и виртуальных функций в коде, тем лучше

Кому-нибудь вообще пригодилось знание механизма вызова виртуальных функций? Мне например только на давних собеседованиях, на которых этим вопросом скорее просто проверяли, а читал ли чел вообще что-нибудь по С++ В реальном коде потребность реализовывать свою VMT, понимать хитровывернутые последовательности вызова функций, обращать пристальное внимание на размер объектов, практически нигде не требуется.
rikimaru2013
C++ Game Dev
 Аватар для rikimaru2013
2137 / 970 / 223
Регистрация: 30.11.2013
Сообщений: 3,240
04.07.2015, 15:31  [ТС]     Принудительный вызов метода родителя #10
Цитата Сообщение от ct0r Посмотреть сообщение
Кому-нибудь вообще пригодилось знание механизма вызова виртуальных функций?
Я с вами не согласен. Если взять поваров: то они работают с ингредиентами и соусами. И лучшим является тот, кто знает как с рыбы взять филе, а еще лучшим тот кто знает чем отличается южный окунь от северного окуня (утрирую). Но разве не так?
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
04.07.2015, 16:20     Принудительный вызов метода родителя #11
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Я с вами не согласен. Если взять поваров: то они работают с ингредиентами и соусами. И лучшим является тот, кто знает как с рыбы взять филе, а еще лучшим тот кто знает чем отличается южный окунь от северного окуня (утрирую). Но разве не так?
Лучшим является тот, кто лучше готовит. Остальное - понты. Вообще вопрос относился к тому, пригодилось ли кому это знание и каким образом. Про нужность или ненужность чего-либо речи не было.
Mr.X
Эксперт С++
 Аватар для Mr.X
2803 / 1579 / 247
Регистрация: 03.05.2010
Сообщений: 3,669
04.07.2015, 17:54     Принудительный вызов метода родителя #12
Цитата Сообщение от ct0r Посмотреть сообщение
Кому-нибудь вообще пригодилось знание механизма вызова виртуальных функций?
Так он вроде бы не стандартизован и от реализации зависит. Какой смысл его знать-то?
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
04.07.2015, 18:42     Принудительный вызов метода родителя #13
Цитата Сообщение от Kastaneda Посмотреть сообщение
не совсем корректно
предлагаю вам проиллюстрировать ваше виденье.

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

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

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

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

Цитата Сообщение от Mr.X Посмотреть сообщение
Так он вроде бы не стандартизован и от реализации зависит. Какой смысл его знать-то?
Ну само собой. Но вопрос не совсем ко мне - я уже говорил, что у меня только на собеседованиях смысл был.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.07.2015, 21:47     Принудительный вызов метода родителя
Еще ссылки по теме:

C++ Вызов метода в потоке
Асинхронный вызов метода с параметрами C++
Вызов метода наследника C++

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

Или воспользуйтесь поиском по форуму:
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
04.07.2015, 21:47     Принудительный вызов метода родителя #16
Цитата Сообщение от ct0r Посмотреть сообщение
Каким образом? Какую проблему это знание помогло решить?
изготовление делегатов
(вызов функции/функции-члена).

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


зато быстро

и потом, такое на собеседовании спрашивают,
что бы отфильтровать программиста от обезъянки.
Yandex
Объявления
04.07.2015, 21:47     Принудительный вызов метода родителя
Ответ Создать тему
Опции темы

Текущее время: 02:35. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru