Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
3 / 3 / 0
Регистрация: 28.11.2018
Сообщений: 242

Как работает "полиморфизм"?

13.01.2020, 02:09. Показов 1921. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Увидел код на лекции, в ютюбе, где объясняли, что текущий полиморфизм в С++ может быть еще быстрее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template<class _Ty>
class A {
public:
    int a;
    void Fun() {
        static_cast<_Ty*>(this)->Fun();
        std::cout << "A\n";
    }
};
 
class B : public A<B> {
public:
    int a;
    void Fun() {
        std::cout << "B\n";
    }
};
 
int main(){
    A<B> *t = new B;
    t->Fun();
}
По правде сказать, такого кол-ва непонятных моментов в одном месте, давно не видел. Как это вообще работает? Т.к. я вроде понимаю..но вроде и нет

static_cast<_Ty*>(this)->Fun(); - не до конца понимаю эту запись. Т.к. при приведении типов, апкаст, переменные себя ведут, наверное, схожим образом, то есть, данные класса выше(по иерархии) остаются, сохраняются. Но...это же переменные; у них, по факту, даже адреса всё также по порядку идут. А функции как? Т.к. я понимаю принцип работы, в данном случае, но не понимаю, как оно устроено "под капотом".

Буду благодарен за развернутый ответ
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.01.2020, 02:09
Ответы с готовыми решениями:

Как работает полиморфизм в C++ на уровне оперативной памяти
Здравствуйте! Возник вопрос чисто теоретического характера. Я знаю (или думаю, что знаю), по каким принципам работает апкаст и...

Объясните как работает полиморфизм на моем примере
Здравствуйте уважаемые. Пожалуйста объясните на моем примере, как это работает. Выдержки из моего кода. class Instrumenti { ...

Не работает полиморфизм
Почему объект использует метод базового класса? Базовый класс: #pragma once #include &quot;System.h&quot; #include...

10
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,227
13.01.2020, 03:13
Лучший ответ Сообщение было отмечено MJ_PRUTYG как решение

Решение

Упростите пример - уберите шаблонность. Получим эквивалентный пример без шаблонов

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class A {
public:
    int a;
    void Fun();
};
 
class B : public A {
public:
    int a;
    void Fun() {
        std::cout << "B\n";
    }
};
 
void A::Fun() {
    static_cast<B*>(this)->Fun();
    std::cout << "A\n";
}
 
int main(){
    A *t = new B;
    t->Fun();
}
Что именно вам здесь не понятно?

Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
Т.к. при приведении типов, апкаст,
О каком именно приведении типов вы ведете речь? static_cast здесь - это downcast, а не upcast.

Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
переменные себя ведут, наверное, схожим образом, то есть, данные класса выше(по иерархии) остаются, сохраняются.
Ни понял вопроса. При чем здесь данные класса и как они могут "не сохраняться"? Приведение типа в данном случае применяется к указателю. На сам объект и какие-либо "данные" это, разумеется, никак не влияет и влиять не может. Они тут вообще никак не участвуют.

Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
что текущий полиморфизм в С++ может быть еще быстрее
Никакого "полиморфизма" в этом коде нет, в классическом понимании термина. Полиморфизм в С++ требует наличия абстрактного общего предка для группы полиморфных классов. В этом коде нет ни общего предка, ни группы полиморфных классов.

Это то, что иногда называют "полиморфизмом времени компиляции". На классический полиморфизм это даже отдаленно не похоже и никак с ним не конкурирует. Поэтому сравнивать их в терминах "еще быстрее" - бессмысленно.
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
13.01.2020, 07:52
Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
По правде сказать, такого кол-ва непонятных моментов в одном месте, давно не видел. Как это вообще работает?
Это попытка навелосипедить девиртуализацию. Неактуально ввиду того что компиляторы уже научились делать подобные оптимизации самостоятельно.
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
13.01.2020, 08:12
MJ_PRUTYG, CRTP
2
3 / 3 / 0
Регистрация: 28.11.2018
Сообщений: 242
14.01.2020, 08:14  [ТС]
Renji, почему не актуально? Т.к. уже несколько человек говорили что используют сей метод для оптимизации ""полиморфизма""
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
14.01.2020, 08:32
Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
Renji, почему не актуально? Т.к. уже несколько человек говорили что используют сей метод для оптимизации ""полиморфизма""
Потому что этот метод уже использует встроенный оптимизатор кода.
У одной виртуальной функции Fun может быть множество различных реализаций. Ради этого ее собственно и делают виртуальной. Чтобы разобраться какая конкретно реализация вам нужна, программа должна лезть в таблицу виртуальных функций. А это дополнительные телодвижения. Если вы точно знаете какая из реализаций нужна, ее можно вызвать напрямую. Что собственно в вашем примере и делается.

Проблема в том, что компиляторы уже достаточно умные чтобы увидеть "Эй, да нет тут никакого множества реализаций! У Fun всего одна версия" и не забивать себе голову какими-то там таблицами. А так как все необходимые оптимизации и так уже делает компилятор, вы только попусту усложняете код.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
14.01.2020, 11:44
Цитата Сообщение от Renji Посмотреть сообщение
А так как все необходимые оптимизации и так уже делает компилятор, вы только попусту усложняете код.
Ну, не все компиляторы это делают, а те, что делают не дают никаких гарантий, даже с максимальными оптимизациями.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
14.01.2020, 11:57
Цитата Сообщение от Azazel-San Посмотреть сообщение
Ну, не все компиляторы это делают, а те, что делают не дают никаких гарантий, даже с максимальными оптимизациями.
На Хабре эта оптимизация еще семь лет тому назад разбиралась, на примере gcc и clang. Думаю, уж за семь лет то оно точно расползлось по всем популярным компиляторам.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
14.01.2020, 12:15
Цитата Сообщение от Renji Посмотреть сообщение
Думаю, уж за семь лет то оно точно расползлось по всем популярным компиляторам.
А, так это были всего лишь ваши догадки?
https://godbolt.org/z/yNeygW
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.01.2020, 12:31
Цитата Сообщение от Renji Посмотреть сообщение
Это попытка навелосипедить девиртуализацию. Неактуально ввиду того что
ввиду того, что бред.

бред потому что вместо девиртуализации получается отказ от виртуальности вообще.
причем завуалированным (через жопнутым) способом.

код, который написан в стартопике можно переписать гораздо проще:

C++
1
2
3
4
5
6
7
8
9
10
11
struct B
{
    void Fun() const noexcept {  std::cout << "B\n"; }
};
 
int main()
{
    B* obj = new B;
    obj->Fun();
    delete obj;
}
вот такой интерфейс:
Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
A<B>
- не нужен.
это бред.

с таким же успехом можно сразу использовать тип B,
и не морочить голову ни себе, ни людям.

Цитата Сообщение от MJ_PRUTYG Посмотреть сообщение
Увидел код на лекции, в ютюбе,
передай этому чуваку с ютюба: Шарик, ты - балбес.
и скинь ему эту ссылку
2
3 / 3 / 0
Регистрация: 28.11.2018
Сообщений: 242
14.01.2020, 17:09  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
с таким же успехом можно сразу использовать тип B
Вот, да, и я об этом! Такие же мысли. Просто зачем так морочиться, если всё равно знаешь что будет вызываться и из-за этого сама суть виртуальности пропадает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.01.2020, 17:09
Помогаю со студенческими работами здесь

Как реализован полиморфизм?
Если я не ошибаюсь, то, благодаря ему, если member-функция fun в базовом классе CBase объявлена как virtual, и перегружена в производном...

Как реализовать полиморфизм
У меня товарищ ходил на собеседовании по работе и там у него спросили как реализовать полиморфизм в си(именно си а не с++) он не знал...

Как правильно реализовать полиморфизм?
Имеется такая иерархия классов //classes.h class CL1 { private: int x; virtual char c;

Как реализовать полиморфизм в игре пятнашки?
Здравствуйте нужно реализовать полиморфизм в игре пятнашки на окнах windows forms. То есть создать abstract класс в котором должен быть...

Как понять данный код (Полиморфизм)?
Здравствуйте! Только начал учить java, до этого кодил на php. Есть код: Строка 24 public class Shape { public void draw() { ...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru