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

Виртуальные функции

30.07.2022, 14:36. Показов 924. Ответов 19

Студворк — интернет-сервис помощи студентам
Добрый день. Имеется следующее задание:

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
Задание 6*. В чем заключается отличие 1) и 2)
    {
        std::cout << "6\n";
 
        Shape* pShapes = new Rect[10]; //1) указатель типа Shape на массив из десяти элементов типа Rect
        Rect* pRects = new Rect[10];   //2) указатель типа Rect на массив из десяти элементов типа Rect
 
        //Попробуйте вызвать метод WhereAmIVirtual() для каждого элемента обоих массивов -
        //в чем заключается проблема???
 
        for (int i = 0; i < 10; i++)
        {
            pShapes[i].WhereAmIVirtual();
        }
 
        for (int i = 0; i < 10; i++)
        {
            pRects[i].WhereAmIVirtual();
        }
        
        //Освободите динамически захваченную память
        delete [] pRects;
        delete[] pShapes;
    }
Подскажите пожалуйста почему в первом цикле выдаёт ошибку ведь по идее должна вызываться виртуальная функция для класса Rect?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.07.2022, 14:36
Ответы с готовыми решениями:

Виртуальные и чисто виртуальные функции
Чем они отличаются?? если можно, с примерами. И как из виртуальной функции сделать чисто виртуальную? #include &lt;iostream&gt; using...

Виртуальные функции.
Приветствую всех. Дана такая программа (на самом деле она больше и сложнее, но структура и проблема те же): #include &lt;iostream&gt; ...

Виртуальные функции
Не работает код. Проблема в виртуальной функции. Как это можно исправить? #include &lt;iostream&gt; class Convert { protected:...

19
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
30.07.2022, 14:41
виртуальная функция вызвалась бы через указатель, вы обращаетесь напрямую к переменным.
И сделали какую-то фигню отрезали в памяти ленту размером 10*8 байт(пусть rect 8 байт) а потом нарезаете её на кусочки по 5 байт(пусть shape 5 байт)
в итоге получается куча мала.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
30.07.2022, 14:44
Nik_787, проблема в том, что в С++ нет полиморфных массивов.

Добавлено через 3 минуты
Nik_787, https://www.cyberforum.ru/post9070017.html
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
30.07.2022, 14:48
0
2 / 2 / 0
Регистрация: 27.11.2021
Сообщений: 129
30.07.2022, 14:52  [ТС]
Kuzia domovenok, если я вызову функцию через указатель то, как я доберусь до каждого члена массива?
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
30.07.2022, 14:52
Цитата Сообщение от DrOffset Посмотреть сообщение
Nik_787, проблема в том, что в С++ нет полиморфных массивов.
вы так говорите, будто это неправильное с точки зрения логики программистов поведение, которое хорошо чтоб было так, но вот незадача... в С++ оно не работает. Но это не так. Мне кажется именно так как сейчас и должны выделяться массивы. Массив это по определению последовательно хранящиеся в памяти переменные одного типа. Пытаться запихнуть в массив яблоки и апельсины зачем? Кому это нужно в программировании?
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
30.07.2022, 14:58
Цитата Сообщение от Nik_787 Посмотреть сообщение
Kuzia domovenok, если я вызову функцию через указатель то, как я доберусь до каждого члена массива?
Дело вообще не в функции. Вы выделили десять ректов и нигде не сказали, что храните 10 ректов, а не 10 шейпов. Всё! Ошибка произошла уже на этом этапе. Нет никакой возможности теперь достать из Shape* pShapes ваши ректы кроме как явно преобразовывать указатель к правильному типу
C++
1
2
Rect* notWrongArray = pShapes;
notWrongArray[0].WhereAmIVirtual();
но если так делать, смысл был вообще тогда делать pShapes? Можно было сразу
C++
1
Rect* notWrongArray = new Rect[10];
0
2 / 2 / 0
Регистрация: 27.11.2021
Сообщений: 129
30.07.2022, 14:59  [ТС]
Я забыл добавить. Что эти классы связаны наследованием Shape базовый, а Rect производный.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
30.07.2022, 15:01
Nik_787, мне это было и так очевидно. Это ничего не меняет в моих словах
0
2 / 2 / 0
Регистрация: 27.11.2021
Сообщений: 129
30.07.2022, 15:13  [ТС]
Теперь нужно Ваши слова осмыслить. Я в указателе типа Shape храню адрес на массив из элементов Rect. Размер адреса всегда одинаковый и от типа не зависит. Я правильно рассуждаю?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
30.07.2022, 15:21
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
вы так говорите, будто это неправильное с точки зрения логики программистов поведение, которое хорошо чтоб было так, но вот незадача... в С++ оно не работает. Но это не так.
Сами что-то придумали, и сами с этим спорим? Ну-ну.
0
2 / 2 / 0
Регистрация: 27.11.2021
Сообщений: 129
30.07.2022, 15:27  [ТС]
Коллеги не ругайтесь.))) Объясните дурочку в чем ошибка . Я так ничего и не понял, если честно.)))
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
30.07.2022, 15:57
Цитата Сообщение от Nik_787 Посмотреть сообщение
Объясните дурочку в чем ошибка
Использование адресной арифметики над указателем типа Shape, который не указывает на элемент массива объектов типа Shape

Добавлено через 7 минут

Не по теме:

Хотя формально pShapes и pShapes + 1 валидные выражения, ожнако разыменовать можно только первый укзатель, т.к. он указывет на подобъект Shape первого объекта массива объектов Rect.

0
2 / 2 / 0
Регистрация: 27.11.2021
Сообщений: 129
30.07.2022, 15:58  [ТС]
Значит, если я правильно понял, при переходе к следующему элементу массива типа рект я не могу попасть в начало этого элемента. Правильно?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
30.07.2022, 16:04
Цитата Сообщение от Nik_787 Посмотреть сообщение
Правильно?
Можно и так сказать.
0
2 / 2 / 0
Регистрация: 27.11.2021
Сообщений: 129
30.07.2022, 16:07  [ТС]
А почему так происходит?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
30.07.2022, 16:14
Цитата Сообщение от Nik_787 Посмотреть сообщение
А почему так происходит?
Адресная арифметика отталкивается от размера типа адресуемого объекта.
Картинка в #4 по идее должна была это прояснить.

Добавлено через 2 минуты
Цитата Сообщение от Nik_787 Посмотреть сообщение
Значит, если я правильно понял, при переходе к следующему элементу массива типа рект я не могу попасть в начало этого элемента. Правильно?
Можете попасть, а можете и не попасть, зависит от размера типов Shape и Rect. Если их размеры равны, то попадете. Правда ситуацию это не исправит, потому что освободить такой массив корректно через указатель на Rect все равно не получится.
0
2 / 2 / 0
Регистрация: 27.11.2021
Сообщений: 129
30.07.2022, 16:16  [ТС]
Спасибо!!!! Теперь всё встало на свои места.
0
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,246
30.07.2022, 17:10
Хочу подытожить:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        Shape* pShapes[10]; //1) массив из десяти указателей на тип Shape
        Rect* pRects[10];   //2) массив из десяти указателей на тип Rect
 
        for (int i = 0; i < 10; i++)
        {
            pShapes[i]=new Rect;
            pShapes[i]->WhereAmIVirtual(); // Виртуальный вызов функции из Rect через указатель на Shape 
        }
 
        for (int i = 0; i < 10; i++)
        {
            pRects[i]=new Rect;
            pRects[i]->WhereAmIVirtual(); // Обычный вызов функции из Rect через указатель на Rect
        }
        
        //Освободите динамически захваченную память
        for (int i = 0; i < 10; i++)
        {
            delete pRects[i];
            delete pShapes[i];
        }
0
2 / 2 / 0
Регистрация: 27.11.2021
Сообщений: 129
30.07.2022, 17:22  [ТС]
Спасибо!!!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.07.2022, 17:22
Помогаю со студенческими работами здесь

Виртуальные функции
Создать абстрактный базовый класс с виртуальной функцией - объем. Создать производные классы: параллелепипед, пирамида, тетраэдр, шар со...

Виртуальные функции С++
Задача: В классе хранится целое, и определяется виртуальная функция shownum(). Создать 2 производных класса, наследующие класс num. В...

Виртуальные функции С++
Всем привет, заполните, пожалуйста, пробелы в моих знаниях. На одном ресурсе прочитал четкое объяснение виртуальной функции ...

Виртуальные функции
Всем привет. Есть задание. Если коротко, то нужно транспонировать матрицу используя ооп. Должно быть наследование и в производном классе...

Виртуальные функции
Вопрос. Как вызвать функцию наследника через указатель на базовый класс? Так не компилируется 3.cpp:19:19: error: invalid covariant...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Вывод данных через динамический список в справочнике
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