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

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

14.05.2023, 17:25. Показов 1110. Ответов 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
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
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
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
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
Ответ Создать тему
Новые блоги и статьи
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru