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

Объясните разницу между функциями virtual и обычными простым языком

14.05.2023, 17:25. Показов 1171. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Написал две программы по аналогии, а в чём разница не понимаю.
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <cmath>
 
using namespace std;
 
// Базовый класс геометрических фигур
class Geom {
protected:
    double area; // площадь
public:
    Geom() {}
    virtual void calc_area() {}
};
 
// Класс круга
class Circle : public Geom {
private:
    double radius; // радиус круга
public:
    Circle(double r) {
        radius = r;
    }
    void calc_area() {
        area = 3.14*pow(radius, 2);
    }
    double get_area() {
        return area;
    }
};
 
// Класс прямоугольника
class Box : public Geom {
private:
    double side1;// длина первой стороны
    double side2;// длина второй стороны
public:
    Box(double s1,double s2) {
        side1 = s1;
        side2 = s2;
        area = side1 * side2;
    }
    double get_area() {
        return area;
    }
};
 
int main() {
    // вводим размеры прямоугольников
    double sa1, sb1, sa2, sb2, sa3, sb3;
    cout << "Enter size a of box 1: ";
    cin >> sa1;
    cout << "Enter size b of box 1: ";
    cin >> sb1;
    cout << "Enter size a of box 2: ";
    cin >> sa2;
    cout << "Enter size b of box 2: ";
    cin >> sb2;
    cout << "Enter size a of box 3: ";
    cin >> sa3;
    cout << "Enter size b of box 3: ";
    cin >> sb3;
 
    // создаем объекты прямоугольников
    Box b1(sa1, sb1);
    Box b2(sa2, sb2);
    Box b3(sa3, sb3);
    // вычисляем сумму площадей прямоугольников
    double bsumS;
    bsumS = b1.get_area() + b2.get_area() + b3.get_area();
    // вводим радиусы кругов
    double r1, r2, r3;
    cout << "Enter size of circle 1: ";
    cin >> r1;
    cout << "Enter size of circle 2: ";
    cin >> r2;
    cout << "Enter size of circle 3: ";
    cin >> r3;
    // создаем объект круга
    Circle cir1(r1);
    Circle cir2(r2);
    Circle cir3(r3);
    // вычисляем сумму площадей кругов
    double csumS,cS1,cS2,cS3;
    cir1.calc_area();
    cir2.calc_area();
    cir3.calc_area();
    csumS = cir1.get_area() + cir2.get_area() + cir3.get_area();
 
 
 
    // выводим результаты
    cout << "Total area of circles: " << csumS << endl;
    cout << "Total are of boxes: " << bsumS << endl;
 
    return 0;
}
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <cmath>
 
using namespace std;
 
// Базовый класс геометрических фигур
class Geom {
protected:
    double area; // площадь
public:
    Geom() {}
    void calc_area() {}
};
 
// Класс круга
class Circle : public Geom {
private:
    double radius; // радиус круга
public:
    Circle(double r) {
        radius = r;
    }
    void calc_area() {
        area = 3.14*pow(radius, 2);
    }
    double get_area() {
        return area;
    }
};
 
// Класс прямоугольника
class Box : public Geom {
private:
    double side1;// длина первой стороны
    double side2;// длина второй стороны
public:
    Box(double s1,double s2) {
        side1 = s1;
        side2 = s2;
        area = side1 * side2;
    }
    double get_area() {
        return area;
    }
};
 
int main() {
    // вводим размеры прямоугольников
    double sa1, sb1, sa2, sb2, sa3, sb3;
    cout << "Enter size a of box 1: ";
    cin >> sa1;
    cout << "Enter size b of box 1: ";
    cin >> sb1;
    cout << "Enter size a of box 2: ";
    cin >> sa2;
    cout << "Enter size b of box 2: ";
    cin >> sb2;
    cout << "Enter size a of box 3: ";
    cin >> sa3;
    cout << "Enter size b of box 3: ";
    cin >> sb3;
 
    // создаем объекты прямоугольников
    Box b1(sa1, sb1);
    Box b2(sa2, sb2);
    Box b3(sa3, sb3);
    // вычисляем сумму площадей прямоугольников
    double bsumS;
    bsumS = b1.get_area() + b2.get_area() + b3.get_area();
    // вводим радиусы кругов
    double r1, r2, r3;
    cout << "Enter size of circle 1: ";
    cin >> r1;
    cout << "Enter size of circle 2: ";
    cin >> r2;
    cout << "Enter size of circle 3: ";
    cin >> r3;
    // создаем объект круга
    Circle cir1(r1);
    Circle cir2(r2);
    Circle cir3(r3);
    // вычисляем сумму площадей кругов
    double csumS,cS1,cS2,cS3;
    cir1.calc_area();
    cir2.calc_area();
    cir3.calc_area();
    csumS = cir1.get_area() + cir2.get_area() + cir3.get_area();
 
 
 
    // выводим результаты
    cout << "Total area of circles: " << csumS << endl;
    cout << "Total are of boxes: " << bsumS << endl;
 
    return 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.05.2023, 17:25
Ответы с готовыми решениями:

Объясните простым языком таблицу истинности
Почему в случае с &quot;&amp;&quot; - false, a в случае с &quot;|&quot; - true? Почему в случае с &quot;^&quot; - true? true &amp; false == false true | false == true ...

Объясните, пожалуйста, простым языком что такое дифференциал
Объясните, пожалуйста, простым языком что такое диференциал.

Объясните пожалуйста предназначение порождающих паттернов простым языком
Вроде и uml выучил для каждого паттерна, и определения знаю, и в коде могу написать. Но не понимаю предназначение каждого из них. ...

18
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
14.05.2023, 17:45
Для тебя разницы нет. Ты не используешь соответствующие возможности.
0
1 / 1 / 0
Регистрация: 17.11.2022
Сообщений: 54
14.05.2023, 17:47  [ТС]
nmcf, Тогда объясните, что я могу сделать, имея класс virtual, пожалуйста
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
14.05.2023, 17:54
Допустим, неизвестно наперёд, какие буду созданы фигуры. Тогда ты объявляешь контейнер с общим типом.
C++
1
2
3
Geom *a[n];
a[0] = new Circle(10);
a[1] = new Box(1, 2);
И далее вызов виртуальных функций будет соответствовать фактическому типу, а не типу массива.
Если же делать без virtual, то будет вызываться функция Geom.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,222
14.05.2023, 18:06
Цитата Сообщение от Castler Посмотреть сообщение
Написал две программы по аналогии
Так а что вообще пытались сделать в этих программах? Почему в классе Circle вычисление площади вынесено в отдельную функцию calc_area, а в классе Box - не вынесено и выполняется прямо в конструкторе?

Тут еще рано говорить о virtual.
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
14.05.2023, 18:11
Немного переделал классы и сделал соответствующий вывод, чтоб показать смысл. И да, calc_area() целесообразно либо убрать и сделать соответствующие вычисления сразу в конструкторе, либо... не хранить площадь в полях класса (например, для экономии оперативы, если геомы слишком много), а делать вычисления в get_area() и сразу же выводить результат. Правда, если get_area() придется вызывать неоднократно, нагрузка на оперативу превратится в лишнюю нагрузку на процессор.
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
54
55
56
57
58
59
#include <iostream>
#include <cmath>
 
using namespace std;
 
// Базовый класс геометрических фигур
class Geom {
protected:
    double area; // площадь
public:
    Geom() {area = 0;}
    virtual double get_area() {
        return area;
    }
};
 
// Класс круга
class Circle : public Geom {
private:
    double radius; // радиус круга
public:
    Circle(double r) {
        radius = r;
        area = 3.14*pow(radius, 2);
    }
    double get_area() override {
        return area;
    }
};
 
// Класс прямоугольника
class Box : public Geom {
private:
    double side1;// длина первой стороны
    double side2;// длина второй стороны
public:
    Box(double s1,double s2) {
        side1 = s1;
        side2 = s2;
        area = side1 * side2;
    }
    double get_area() override {
        return area;
    }
};
 
int main() {
    Geom geom[4];
 
    geom[0] = Circle(1);
    geom[1] = Box(2, 2);
    geom[2] = Circle(3);
    geom[3] = Box(4, 4);
 
    for (int i=0; i<4; i++)
        cout << geom[i].get_area() << endl;
 
    return 0;
}
1
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
14.05.2023, 18:21
Anvis, это ты так хитро задумал или в чём смысл 50-53?
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
14.05.2023, 18:28
Цитата Сообщение от nmcf Посмотреть сообщение
это ты так хитро задумал или в чём смысл 50-53?
Инициализация массива классами различных фигур. Я допускаю какую-то ошибку?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
14.05.2023, 18:39
Цитата Сообщение от Anvis Посмотреть сообщение
Я допускаю какую-то ошибку?
Если убрать virtual и реализацию у наследников(зачем она кстати?), поведение не изменится.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
14.05.2023, 18:44
Castler,
Цитата Сообщение от Anvis Посмотреть сообщение
чтоб показать смысл
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
54
55
56
57
#include <iostream>
#include <cmath>
 
using namespace std;
 
// Базовый класс геометрических фигур
class Geom {
protected:
    double area; // площадь
public:
    Geom() {area = 0;}
    virtual double get_area() {
        return area;
    }
};
 
// Класс круга
class Circle : public Geom {
private:
    double radius; // радиус круга
public:
    Circle(double r) {
        radius = r;
    }
    double get_area() override {
        return 3.14*pow(radius, 2);
    }
};
 
// Класс прямоугольника
class Box : public Geom {
private:
    double side1;// длина первой стороны
    double side2;// длина второй стороны
public:
    Box(double s1,double s2) {
        side1 = s1;
        side2 = s2;
    }
    double get_area() override {
        return side1 * side2;
    }
};
 
int main() {
    Geom * geom[4];
 
    geom[0] = new Circle(1);
    geom[1] = new Box(2, 2);
    geom[2] = new Circle(3);
    geom[3] = new Box(4, 4);
 
    for (int i=0; i<4; i++)
        cout << geom[i]->get_area() << endl;
 
    return 0;
}
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
14.05.2023, 18:47
_stanislav, зачем тогда член Geom::area оставил?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
14.05.2023, 18:49
Цитата Сообщение от Anvis Посмотреть сообщение
Я допускаю какую-то ошибку?
Ты просто преобразуешь объекты в родительский Geom. Вот я и спрашиваю: так задумано?
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
14.05.2023, 18:52
Цитата Сообщение от zayats80888 Посмотреть сообщение
зачем тогда член Geom::area оставил?
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
54
#include <iostream>
#include <memory>
#include <cmath>
 
using namespace std;
 
// Базовый класс геометрических фигур
class Geom {
public:
    virtual ~Geom() = default;
    virtual double get_area() = 0;
};
 
// Класс круга
class Circle : public Geom {
private:
    double radius; // радиус круга
public:
    Circle(double r) {
        radius = r;
    }
    double get_area() override {
        return 3.14*pow(radius, 2);
    }
};
 
// Класс прямоугольника
class Box : public Geom {
private:
    double side1;// длина первой стороны
    double side2;// длина второй стороны
public:
    Box(double s1,double s2) {
        side1 = s1;
        side2 = s2;
    }
    double get_area() override {
        return side1 * side2;
    }
};
 
int main() {
    std::unique_ptr< Geom > geom[4];
 
    geom[0] = std::unique_ptr< Geom >( new Circle(1) );
    geom[1] = std::unique_ptr< Geom >( new Box(2, 2) );
    geom[2] = std::unique_ptr< Geom >( new Circle(3) );
    geom[3] = std::unique_ptr< Geom >( new Box(4, 4) );
 
    for (int i=0; i<4; i++)
        cout << geom[i]->get_area() << endl;
 
    return 0;
}
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
14.05.2023, 18:53
zayats80888, действительно. Никогда не использовал виртуальные методы для статических объектов, однако в примере убрал динамическое создание специально, чтобы сделать код как можно нагляднее.
0
14.05.2023, 18:57

Не по теме:

Цитата Сообщение от Anvis Посмотреть сообщение
виртуальные методы для статических объектов
Что за "статические" объекты?
З.Ы. А вы код редактировали или я в глаза долблюсь? Я вроде там у вас new видел, а теперь там вообще треш...

0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
14.05.2023, 19:09
Цитата Сообщение от zayats80888 Посмотреть сообщение
или я в глаза долблюсь?
Долбитесь. В моем примере new не было изначально. А вот с area и get_area() действительно допустил большой косяк...
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,222
14.05.2023, 19:21
Цитата Сообщение от Anvis Посмотреть сообщение
Немного переделал классы и сделал соответствующий вывод, чтоб показать смысл.
Получилась ерунда. В вашем коде нет никакого полиморфизма вооще, а все классы при инициализации массива просто тупо "слайсятся" до Geom. То есть ваш код - скорее иллюстрация распространненой ошибки со "слайсингом".
0
14.05.2023, 19:23

Не по теме:

Цитата Сообщение от Anvis Посмотреть сообщение
В моем примере new не было изначально. А вот с area и get_area() действительно допустил большой косяк...
"Большой косяк" как раз в строках 50-53 и его не исправить через
Цитата Сообщение от Anvis Посмотреть сообщение
area и get_area()

0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
14.05.2023, 19:32
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
То есть ваш код - скорее иллюстрация распространненой ошибки со "слайсингом"
Да понял я уже. Ошибка возникла из желания максимально упростить код, написав его без указателей, а сработал он "как и задумывалось", потому что когда думал, зачем у ТС нужен calc_area() и переносил формулу в конструктор, не заметил, как создал три одинаковых метода get_area(). Дело в том, что я действительно никогда раньше не пробовал работать со статическими экземплярами с наследованием.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.05.2023, 19:32
Помогаю со студенческими работами здесь

Объясните простым языком, что делает блок кода
Это код выводы поля с найденным путем Что происходит в коде? а именно, как работает массив switch? почему есть просто кейсы от 1 до 20? ...

Объясните пожалуйста простым языком про Pathos Pool.map()
Общая схема применения мультипроцессинга такая или нет? from pathos.multiprocessing import ProcessingPool as Pool p=Pool() def...

Объясните, пожалуйста, как строить поля из n элементов самым простым и понятным языком
Здравствуйте. Объясните, пожалуйста, как строить поля из n элементов самым простым и понятным языком(например, из 9 или 16 элементов). ...

Объясните пожалуйста более менее, если это возможно, простым языком принципы ООП
Не получается понять смысл и значение Инкапсуляции, Полиморфизма и Наследования. Пересмотрел множество сайтов и видео, но что-то всё равно...

Объясните разницу между C# и C++
Часто встречаю на форуме, что мол C++ мощнее C#. Можно услышать ответ проффесионала, в чем конкретно разница и какие ограничения в C#, а...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
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. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru