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

Вызов виртуальной функции через указатель на базовый класс

16.06.2014, 16:21. Показов 3796. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет! Помогите пожалуйста разобраться с вызовом виртуальной функции в программе.

В моей программе требуется организовать класс треугольник, определенный по длинам трех сторон содержащий методы нахождения периметра и площади (по формуле Герона).

А так же определить виртуальную функцию для нахождения площади таким образом, чтобы в базовом и производном классе тела функций определялись по-разному.

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

Программа состоит из 3-х файлов, помогите пожалуйста разобраться с объявлением виртуальной функции:

main:
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
#include "MyTriangle.cpp"
#include <iostream>
#include <windows.h>
using namespace std;
 
MyTriangle enter(){
    
    float x1, x2, x3; 
    cout << "Введите длину стороны A" << endl; 
    cin >> x1;
    cout << "Введите длину стороны B" << endl; 
    cin >> x2;  
    cout << "Введите длину стороны C" << endl; 
    cin >> x3;
    return MyTriangle(x1, x2, x3);
} 
 
void func() {
    MyTriangle tr;
    int number; 
    cout << "Введите данные треугольника " << endl;
    tr = enter();  
    cout << endl;
    cout << "1 Площадь по формуле Герона" << endl;
    cout << "2 Периметр " << endl;
    cout << "3 Высота " << endl;
    cout << "4 Площадь по высоте и основанию (Виртуальная функция)" << endl;
    cout << "5 Углы треугольника " << endl;
    cout << "6 Полное описание треугольника " << endl;
    cout << "Выберите что вы хотите сделать ваш вариант " << endl; 
    cin >> number; 
 
    switch(number) { 
        case 1: cout << "Площадь равна " << tr.newArea() << endl; break; 
        case 2: cout << "Периметр равен " << tr.perimetr() << endl; break; 
        case 3: cout << "Высота равна " << tr.height() << endl; break;
        case 4: cout << "Площадь по высоте и основанию равна " << tr.areaIsHeight() << endl; break; 
        case 5: tr.angle1(); break;
        case 6: cout << "Площадь равна (Виртуальная функция) " << tr.newArea() << endl;
         cout << "Периметр равен " << tr.perimetr() << endl;
         cout << "Высота равна " << tr.height() << endl;
         cout << "Площадь равна (формула Герона)  " << tr.areaIsHeight() << endl;
         tr.angle1(); break; 
        default: cout << "Не корректный ввод данных " << endl; break;
    }
}    
int main() {   
    setlocale(0, "rus"); 
    int k;
    cout << "1.Вводить данные" << endl;
    cout << "2.Выйти из программы" << endl;
    while(true){
        cout << "Введите номер операции" << endl; 
        cin >> k;
        switch(k) {
            case 1 : system("cls"); func(); break;
            case 2 : exit(EXIT_SUCCESS); break;
            default : cout << "Некорректный ввод данных" << endl;
        }
    }   
}
Triangle:
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
#include <iostream>
#include <cmath>
 
using namespace std;
 
class Triangle { 
    private: 
        float x1, x2, x3; 
        
    public: 
        Triangle() {}
        Triangle(float, float, float);
        ~Triangle() {}
        float perimetr(); 
        float height();
        float area2();
        void angle();
    const virtual float newArea() const {
        float p2 = (x1 + x2 + x3) / 2;
        float height = (2 * sqrt(p2 * (p2 - x1) * (p2 - x2) * (p2 - x3))) / x1;
        return 0.5 * x1 * height;
    }
}; 
 
Triangle::Triangle(float x1, float x2, float x3){
    this->x1 = x1;
    this->x2 = x2;
    this->x3 = x3; 
}
         
float Triangle :: area2() {
    float p2 = perimetr()/2;
    return sqrt(p2 * (p2 - x1) * (p2 - x2) * (p2 - x3));
} 
 
float Triangle :: perimetr() {
    return x1 + x2 + x3;  
} 
 
float Triangle :: height() { 
    float p2 = perimetr() / 2;
    return (2 * area2()) / x1;
}
 
void Triangle :: angle() {
    float A = (acos(cos((pow(x3, 2) + pow(x2, 2) - pow(x1, 2)) / (2 * x2 * x3))) * 180) / 3.14;
    float B = (acos(cos((pow(x1, 2) + pow(x3, 2) - pow(x2, 2)) / (2 * x1 * x3))) * 180) / 3.14;
    float C = 180 - (A + B);
    cout << "Угол А = " << A << " Угол В = " << B << " Угол С = " << C << endl;
}
MyTriangle:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "Triangle.cpp"
 
class MyTriangle : public Triangle {
    public:
        MyTriangle() : Triangle() {}
        MyTriangle(float x1, float x2, float x3) :
            Triangle(x1, x2, x3) {}
        float areaIsHeight();
        float height1();
        void angle1();
};
 
float MyTriangle :: areaIsHeight() {
    return area2();
}
 
float MyTriangle :: height1() {
    return height();
}
 
void MyTriangle :: angle1() {
    angle();
}
Программу писал мой однокурсник... Он тоже сдавал ее, преподаватель ее принял. А мне вот не повезло...
Очень надеюсь на Вашу помощь!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.06.2014, 16:21
Ответы с готовыми решениями:

Вызов виртуальной функции, определённой в дочернем классе, через указатель на базовый класс
Как вызвать виртуальную функцию, определённую в дочернем классе, через указатель на базовый класс? Совершенно точно известно, что на...

Вызов метода производного класса через указатель на базовый класс
Всем привет ! Подскажите почему , при выполнении строки 45 я получаю ошибку ? А именно при выполнении выражения c-&gt;fnz() ...

Указатель на базовый класс и дружественные функции
Здравствуйте. У меня есть базовый класс Number-простое целое число типа long int. В классе имеется 2 дружественных функции, перегрузка...

8
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.06.2014, 16:25
Ну так она объявлена виртуальной в базовом, а во втором не переопределена.
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
16.06.2014, 16:47
Цитата Сообщение от Xaklex Посмотреть сообщение
C++
1
2
3
MyTriangle tr;
//...
cout << "Площадь равна (Виртуальная функция) " << tr.newArea()
Вы, по-моему, вообще не понимаете для чего нужны виртуальные функции.
Для вызова виртуальной функции надо иметь указатель или ссылку на базовый класс, а так получается вызов, который заранее известен на момент компиляции.
2
0 / 0 / 0
Регистрация: 20.04.2014
Сообщений: 4
16.06.2014, 18:58  [ТС]
А как тогда можно в данной программе вызвать виртуальную функцию? Tulosba, Вы правы, с виртуальными функциями у меня туго... Но пытаюсь как могу разобраться.

Возможно, программу нужно как-то подкорректировать, чтобы она содержала вызов виртуальной функции? Если это возможно, подскажите пожалуйста, каким образом? Заранее спасибо)
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.06.2014, 19:18
Ты сначала создай то, что можно вызывать. В MyTriangle функции newArea() нет.
1
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,244
16.06.2014, 19:25
Цитата Сообщение от Xaklex Посмотреть сообщение
MyTriangle tr;
Вместо этого надо
C++
1
Triangle* tr=new MyTriangle;
Вызов виртуальной функции:
C++
1
 cout << "Площадь равна (Виртуальная функция) " << tr->newArea() << endl;
1
0 / 0 / 0
Регистрация: 20.04.2014
Сообщений: 4
17.06.2014, 03:39  [ТС]
nmcf, хорошо, попробую добавить виртуальную функцию в MyTriangle, спасибо)

zss, строку переделаю, но про вызов виртуальной функции:
C++
1
 cout << "Площадь равна (Виртуальная функция) " << tr->newArea() << endl;
Я говорил преподавателю о том, что это и есть вызов, на что он мне ответил: "Виртуальная функция вызывается только через указатель на базовый класс". Но все равно, спасибо за ответ)
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
17.06.2014, 04:17
Цитата Сообщение от Xaklex Посмотреть сообщение
Я говорил преподавателю о том, что это и есть вызов, на что он мне ответил: "Виртуальная функция вызывается только через указатель на базовый класс".
И все дружно это подтверждают. zss, показывает как создать объект с доступом через указатель и потом через указатель же и вызвать метод. Причем указатель базового класса инициализируется адресом объекта производного класса. Повторите указатели и потом перечитайте наследование иначе будете "всё равно спасибо" ещё долго говорить.
1
0 / 0 / 0
Регистрация: 20.04.2014
Сообщений: 4
18.06.2014, 14:36  [ТС]
IGPIGP, я всегда благодарен даже просто тому, что мне ответили С программой я разобрался, преподаватель подсказал мне все-таки еще немного (достал я его). Программирование мне нравится, с предыдущими темами разобрался без особой сложности. Но вот с виртуальными функциями почему-то возникли затруднения... Сейчас уже все позади Думаю, в будущем с виртуальными функциями придется сталкивать не раз. Поэтому буду углубляться в эту тему дальше. А то "бегать" от данного метода не горю желанием) И еще раз говорю всем, кто ответил мне, огромное спасибо за отзывчивость и ответы на простом, доступном языке
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.06.2014, 14:36
Помогаю со студенческими работами здесь

Создание объекта через указатель на базовый абстрактный класс
Есть абстрактный класс, от него наследуется 3 класса. В программе предусмотрено создание нового объекта(добавление клиента страховой...

Передача в контейнер объекта через указатель на базовый класс
Передаю в stl контейнер list указатель на производный класс, предварительно приведя его к типу производного класса - программа вылетает.В...

Запись объекта в файл через указатель на базовый класс
Можно ли при помощи write как-нибудь записать массив объектов производных классов в файл, используя для обращения к ним указатель на...

Возможно ли вызвать метод наследника через указатель на базовый класс
Возможно ли вызвать метод наследника,через указатель на базовый класс, если он не определён как виртуальный или этого метода просто нет в...

Преобразование типа при вызове виртуального метода через указатель на базовый класс
Доброго времени суток. Наткнулся на вот такой вопрос в сети и пока что не смог на него ответить, может быть у Вас получится: В каких...


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

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