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

Почему не работает виртуальная функция?

26.08.2021, 18:04. Показов 2649. Ответов 13
Метки c++ (Все метки)

Студворк — интернет-сервис помощи студентам
Почему видает ошибку и виртуальние функция визовается только из базового класа?
C++ (Qt)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <cstring>
#include "Windows.h"
using namespace std;
#include <iomanip>
 
 
class TwoDShape {
 
    double width; double height;
    char name[20];
public:
 
    TwoDShape() {
        width = height = 0.0;
        strcpy_s(name, "unknow");
    
    }
 
    TwoDShape(double w, double h, const char* n) {
        width = w; height = h; strcpy_s(name, n);
    }
 
    TwoDShape(double x, const char* m) {
        width = height = x;
        strcpy_s(name, m);
    }
 
 
    void showDim() {
        cout << "Width " << width << "Height " << height << endl;
    }
 
 
    double getWidth() { return width; }
    double getHeight() { return height; }
    void setWidth(double w) { width = w; }
    void setHeight(double h) { height = h; }
 
    char* getName() { return name; }
 
    virtual double area() {
        cout << "Area must be rechang";
        return 0.0;
    }
 
 
};
 
 
 
class Triangle :public TwoDShape {
 
    char style[20];
public:
 
    Triangle() {
        strcpy_s(style, "unknow");
    }
 
 
    Triangle(const char *st,double w,double h):TwoDShape(w,h,"triangle") {
 
        strcpy_s(style, st);
    }
 
    Triangle(double x) :TwoDShape(x,"triangle") {
        strcpy_s(style, "rivnobedrenuy");
 
    }
 
 
    double area() {
 
        return getWidth() * getHeight() / 2;
    }
 
    void showStyle() {
        cout << style << endl;
 
    }
};
 
class Rectangl :public TwoDShape {
 
public:
 
    Rectangl(double w, double h) :TwoDShape(w, h,"prymokutnik") {}
    Rectangl(double k) :TwoDShape(k,"prymokutnik") {}
 
    bool isSquare() {
        if (getWidth() == getHeight()) return true;
        return false;
    }
 
    double area() {
        return getWidth() * getHeight() / 2;
    }
 
 
};
 
int main() {
 
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    TwoDShape *mas[5];
 
    mas[0] = &Triangle("pryamokutniy",7,4);
    mas[1] = &Rectangl(10);
    mas[2] = &Rectangl(10, 4);
    mas[3] = &Triangle(7.0);
    mas[4] = &TwoDShape(10, 20, "zagalfigure");
 
    for (int i = 0; i < 5; i++) {
        
        cout << "Object is:" << mas[i]->getName() << endl;
        cout << "Area is:" <<mas[i]->area()<<endl<<endl;
    }
 
 
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.08.2021, 18:04
Ответы с готовыми решениями:

Чистая виртуальная функция функция не имеет оператора переопределения
Пишу программу для записи заметок. Есть 2 класса: Page и Note. Note наследуется от Page. Page.h #pragma once ...

Почему не работает функция?
Вот понадобилась функция для взятия остатка от деления нецелых чисел написал такую: long double OperationDouble( long double a , long...

Почему не работает функция?
Почему не работает функция? function CircleMove() { document.getElementById(&quot;crazycircle&quot;).onmouseover = function(event) { ...

13
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,244
26.08.2021, 19:54
Я такое
Цитата Сообщение от mentalitet235 Посмотреть сообщение
mas[0] = &Triangle("pryamokutniy",7,4);
вижу в первый раз, но, как ни странно,
В VS2008 и VS2017 работает правильно:
0
фрилансер
 Аватар для Алексей1153
6462 / 5670 / 1131
Регистрация: 11.10.2019
Сообщений: 15,100
26.08.2021, 20:02
Цитата Сообщение от mentalitet235 Посмотреть сообщение
mas[0] = &Triangle("pryamokutniy",7,4);
    mas[1] = &Rectangl(10);
    mas[2] = &Rectangl(10, 4);
    mas[3] = &Triangle(7.0);
    mas[4] = &TwoDShape(10, 20, "zagalfigure");
взятие адресов временных объектов - компилятор даже не даёт это скомпилировать (к счастью)
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,235
26.08.2021, 20:03
Цитата Сообщение от mentalitet235 Посмотреть сообщение
Почему видает ошибку
Кто "видает ошибку"? Какую ошибку?

Цитата Сообщение от mentalitet235 Посмотреть сообщение
C++
1
2
3
4
5
    mas[0] = &Triangle("pryamokutniy",7,4);
    mas[1] = &Rectangl(10);
    mas[2] = &Rectangl(10, 4);
    mas[3] = &Triangle(7.0);
    mas[4] = &TwoDShape(10, 20, "zagalfigure");
Это невозможно даже скомпилировать. В С++ запрещается применять встроенный оператор & к временным объектам.

Что вы тут пытались сделать?
0
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,244
26.08.2021, 20:12
TheCalligrapher, а почему они временные?
Они же находятся в области видимости с mas.

Компилятор предупреждения выдает:
warning C4238: нестандартное расширение: использование правостороннего значения класса в качестве левостороннего значения
но работает правильно.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,235
26.08.2021, 20:35
Цитата Сообщение от zss Посмотреть сообщение
TheCalligrapher, а почему они временные?
Вы меня удивляете. Выражение Класс(параметры конструктора) в С++ порождает временный объект типа Класс. Это же весьма заезженная тема (и часто встречающаяся здесь ошибка, когда новички таким образом пытаются вызвать конструктор базового класса).

Цитата Сообщение от zss Посмотреть сообщение
но работает правильно.
Нет, конечно. Даже с этим расширением, продления времени жизни объекта не делается: временный объект все равно уничтожается сразу по завершению выражения. То есть все полученные указатели остаются указывать в никуда. А "работает правильно" оно лишь благодаря тому, что эти классы слишком тривиальны и в памяти после уничтожения объекта остается некий "правильный мусор".

Попробуйте

C++
1
2
3
4
5
6
7
8
#include <string>
#include <iostream>
 
int main() 
{
  std::string *p = &std::string("mama myla ramu");
  std::cout << *p << std::endl;
}
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.08.2021, 20:41
Цитата Сообщение от zss Посмотреть сообщение
но работает правильно.
Это UB. Объект мертв на момент вызова виртуальной функции.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,235
26.08.2021, 20:46
Цитата Сообщение от zss Посмотреть сообщение
но работает правильно.
... к тому же вы, наверное, дебажную версию "тестировали"? Скомпилируйте релизную и посмотрите еще раз, как оно "работает правильно".
1
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
27.08.2021, 10:20
Цитата Сообщение от zss Посмотреть сообщение
warning C4238: нестандартное расширение: использование правостороннего значения класса в качестве левостороннего значения
MSVC открывает для меня всё новые способы выстрелить себе в ногу.
Цитата Сообщение от mentalitet235 Посмотреть сообщение
виртуальние функция визовается только из базового класа
К сожалению, не имею под рукой MSVC, чтоб посмотреть, как там работает, но если поправить создание объектов, то вызов виртуальных функций происходит как ожидается.

Что вам кажется ошибкой?
0
0 / 0 / 0
Регистрация: 27.05.2021
Сообщений: 108
27.08.2021, 11:35  [ТС]
А как мне исправить ошибку?
0
фрилансер
 Аватар для Алексей1153
6462 / 5670 / 1131
Регистрация: 11.10.2019
Сообщений: 15,100
27.08.2021, 11:43
mentalitet235, создавай динамически

C++
1
2
3
4
5
    mas[0] = new Triangle("pryamokutniy",7,4);
    mas[1] = new Rectangl(10);
    mas[2] = new Rectangl(10, 4);
    mas[3] = new Triangle(7.0);
    mas[4] = new TwoDShape(10, 20, "zagalfigure");
а потом не забудь освободить память, чтобы не было утечки

а ещё добавь виртуальный деструктор в класс TwoDShape
0
0 / 0 / 0
Регистрация: 27.05.2021
Сообщений: 108
27.08.2021, 11:53  [ТС]
Ой не смогу ,я только учу ету тему, ищо с деструктором для виртуальних функций не сталкивался.

Добавлено через 8 секунд
Спасибо
0
фрилансер
 Аватар для Алексей1153
6462 / 5670 / 1131
Регистрация: 11.10.2019
Сообщений: 15,100
27.08.2021, 12:15
mentalitet235,
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
//#include <cstring>
#include <string>
//#include "Windows.h"
//using namespace std;
//#include <iomanip>
 
 
class TwoDShape {
 
    double width{};
    double height{};
    std::string name{"unknow"};
public:
 
    TwoDShape()=default;
    virtual ~TwoDShape()=default;
 
    TwoDShape(const double width, const double height, const char* name)
        :width(width)
        ,height(height)
        ,name(name)
    {
    }
 
    TwoDShape(double x, const char* m):TwoDShape(x,x,m)
    {
    }
 
    void showDim()
    {
        std::cout << "Width " << width << "Height " << height << '\n';
    }
 
    double getWidth()const { return width; }
    double getHeight()const { return height; }
    void setWidth(double w) { width = w; }
    void setHeight(double h) { height = h; }
 
    std::string getName()const { return name; }
 
    virtual double area()const
    {
        std::cout << "(Area must be rechang) ";
        return 0.0;
    }
};
 
class Triangle :public TwoDShape {
 
    std::string style{"unknow"};
public:
 
    Triangle()=default;
 
    Triangle(const char *style,double w,double h)
        :TwoDShape(w,h,"triangle")
        ,style(style)
    {
    }
 
    Triangle(double x)
        :TwoDShape(x,"triangle")
        ,style("rivnobedrenuy")
    {
    }
 
    double area()const override {
 
        return getWidth() * getHeight() / 2;
    }
 
    void showStyle()const
    {
        std::cout << style << '\n';
    }
};
 
class Rectangl :public TwoDShape {
 
public:
    Rectangl()=default;
    Rectangl(double w, double h) :TwoDShape(w, h,"prymokutnik") {}
    Rectangl(double k) :TwoDShape(k,"prymokutnik") {}
 
    bool isSquare()const {
        if (getWidth() == getHeight()) return true;
        return false;
    }
 
    double area()const override {
        return getWidth() * getHeight() / 2;
    }
};
 
int main() {
 
   // SetConsoleCP(1251);
   // SetConsoleOutputCP(1251);
 
    TwoDShape* mas[]=
    {
        new Triangle("pryamokutniy",7,4),
        new Rectangl(10),
        new Rectangl(10, 4),
        new Triangle(7.0),
        new TwoDShape(10, 20, "zagalfigure"),
    };
 
    for (const TwoDShape* i:mas)
    {
        if(!i)continue;
        std::cout << "Object is:" << i->getName() <<",  ";
        std::cout << "Area is:" <<i->area()<<'\n';
    }
    
    for (TwoDShape*& i:mas)
    {
        delete i;
        i=nullptr;
    }
 
    return 0;
}
1
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,244
27.08.2021, 14:10
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main() {
 
    //SetConsoleCP(1251); не используется
    //SetConsoleOutputCP(1251);  не используется
 
    TwoDShape *mas[5];
 
    mas[0] = new Triangle("pryamokutniy",7,4);
    mas[1] = new Rectangl(10);
    mas[2] = new Rectangl(10, 4);
    mas[3] = new Triangle(7.0);
    mas[4] = new TwoDShape(10, 20, "zagalfigure");
 
    for (int i = 0; i < 5; i++) {
        
        cout << "Object is:" << mas[i]->getName() << endl;
        cout << "Area is:" <<mas[i]->area()<<endl<<endl;
    }
    for (int i = 0; i < 5; i++) {
         delete[] mas[i]; 
 
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.08.2021, 14:10
Помогаю со студенческими работами здесь

Почему-то не работает функция
Функция запрашивает у php массив склонений для текстовой строки function sklonen(str) { // alert(str); if (str.length==0) { ...

Почему не работает функция gets?
Почему не работает функция gets? Visual Studio // ConsoleApplication6.cpp: определяет точку входа для консольного приложения. // ...

почему функция не работает
#include &lt;iostream&gt; #include &lt;windows.h&gt; using namespace std; int main() { ShellExecute ( hwndYourWindow, &quot;open&quot;,...

Почему функция не работает?
#include &lt;conio.h&gt; #include &lt;iostream&gt; using namespace std; void getFirstWord(char* str) { while (*str != ' ' &amp;&amp; *str !=...

Почему функция не работает?
Читал учебник по haskell: &quot;Изучай Haskell во имя добра!&quot;. Там упоминается использование таких функций как: 1) boomBangs xs = 2)...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru