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

Создать класс четырехугольников, квадратов и прямоугольников

22.10.2022, 18:13. Показов 1532. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Создать класс четырехугольников, квадратов и прямоугольников. Создать из них иерархию. Определить функции печати, конструкторы и деструкторы, вычисление площади и периметра. Функции вычисления площади и периметра должна быть виртуальными. Программа должна содержать меню, позволяющее осуществить проверку всех методов классов.


Иерархия - это дочерние классы? Т.е, четырёхугольник (главный) -> прямоугольник -> квадрат?
Как определить функции печати (это что такое?)
Для виртуальности функций нужно просто virtual перед ними поставить?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.10.2022, 18:13
Ответы с готовыми решениями:

Создать класс четырехугольников, квадратов и прямоугольников (иерархия)
Создать класс четырехугольников, квадратов и прямоугольников. Создать из них иерархию. Определить функции печати, конструкторы и...

Создать структуру параллелограмм, посчитать количество квадратов и прямоугольников (ошибки)
#include<iostream> using namespace std; #include<Windows.h> #include<fstream> int main(void) { SetConsoleCP(1251); ...

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

6
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
22.10.2022, 18:46
Лучший ответ Сообщение было отмечено Suppas15 как решение

Решение

Цитата Сообщение от Suppas15 Посмотреть сообщение
Иерархия - это дочерние классы? Т.е, четырёхугольник (главный) -> прямоугольник -> квадрат?
Да. Обычно это отношение типа "является" плюс "ведёт себя как". В ООП это выражается через наследование.

Цитата Сообщение от Suppas15 Посмотреть сообщение
Как определить функции печати (это что такое?)
Б-г его знает, что имел в виду преподаватель, но я рекомендую для удобства делать вывод используя оператор "<<".
Тогда можно писать std::cout << object;, что красиво и удобно.

Пример
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
#include <iostream>
#include <vector>
 
class Square {
public:
    Square(float side) : side(side) {}
 
    float getSide() const {
        return side;
    }
 
private:
    float side;
};
 
class Quadrangle {
public:
    Quadrangle(float a, float b, float c, float d) : a(a), b(b), c(c), d(d) {}
 
    float getA() const {
        return a;
    }
 
    float getB() const {
        return b;
    }
 
    float getC() const {
        return c;
    }
 
    float getD() const {
        return d;
    }
 
private:
    float a, b, c, d;
};
 
class Rectangle {
public:
    Rectangle(float a, float b) : a(a), b(b) {}
 
    float getA() const {
        return a;
    }
 
    float getB() const {
        return b;
    }
 
private:
    float a, b;
};
 
std::ostream &operator<<(std::ostream &out, const Square &s) {
    return out << "Square{side=" << s.getSide() << "}";
}
 
std::ostream &operator<<(std::ostream &out, const Quadrangle &s) {
    return out << "Quadrangle{"
               << "a=" << s.getA() << ", "
               << "b=" << s.getB() << ", "
               << "c=" << s.getC() << ", "
               << "d=" << s.getD() << "}";
}
 
std::ostream &operator<<(std::ostream &out, const Rectangle &s) {
    return out << "Rectangle{"
               << "a=" << s.getA() << ", "
               << "b=" << s.getB() << "}";
}
 
int main() {
 
    std::cout << Square(1.2) << "\n"
        << Quadrangle(2.2, 3.3, 4.4, 5.5) << "\n"
        << Rectangle(0.23, 3.3);
 
    return 0;
}


Цитата Сообщение от Suppas15 Посмотреть сообщение
Для виртуальности функций нужно просто virtual перед ними поставить?
Достаточно поставить virtual у самых родительских.
Остальным можно дописать override.

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

Поэтому наследование будет иметь смысл только если у этих классов не будет поведения.
В принципе, скорее всего будет достаточно сделать их немутабельными.
То бишь, сделать так, чтоб после создания данные в этих классах нельзя было изменить.
1
6 / 5 / 1
Регистрация: 04.04.2022
Сообщений: 85
22.10.2022, 18:56  [ТС]
lemegeton, Спасибо, понял.
0
6 / 5 / 1
Регистрация: 04.04.2022
Сообщений: 85
23.10.2022, 15:02  [ТС]
Задание:
Создать класс четырехугольников, квадратов и прямоугольников. Создать из них иерархию. Определить функции печати, конструкторы и деструкторы, вычисление площади и периметра. Функции вычисления площади и периметра должна быть виртуальными. Программа должна содержать меню, позволяющее осуществить проверку всех методов классов.

Знаю, что код полная шляпа, пытаюсь улучшить:
1) Как сделать так, чтобы он в меню реально возвращался к выбору фигуры, а не завершал всю программу через return 0? (лучшего не придумал)
2)Как сделать функции виртуальными? Не нашёл родительских функций (скорее всего, у меня их и нет)
3)Где тут вообще можно "вставить" деструкторы и конструкторы (не по умолчанию), или можно без них?

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
#include <iostream>
#include <cmath>
using namespace std;
 
class Quad
{
    public:
    float a,b;
    void SetSides() 
    {
        cout << "Введите значения сторон фигуры (Длину a и ширину b, через пробел)";
        cin >> a;
        cin >> b;
    }
};
class Rectangle : public Quad
{
    public:
    void GetSquare() 
    {
        if (a!=b){
        cout << "Площадь прямоугольника = " << a*b << endl << endl;
        }
        else {
        cout << "Длина не может быть равна ширине в прямоугольнике, не явл. квадратом" << endl;
        }
        }
    void GetSquare1()
    {
        if (a==b){
        cout << "Площадь квадрата = " << a*a << endl << endl;
        }
            else{
        cout << "Все стороны квадрата должны быть равны (a=b)" << endl;
            }
    }
    
    void GetPerimeter() 
    {
        if (a!=b){
        cout << "Периметр прямоугольника = " << (a+b)*2 << endl;
        }
        else{
        cout << "Длина не может быть равна ширине в прямоугольнике, не явл. квадратом" << endl;
        }
    }
    void GetPerimeter1()
    {
        if (a==b){
            cout << "Периметр квадрата = " << a*4 << endl;
        }
        else{
        cout << "Все стороны квадрата должны быть равны (a=b)" << endl;
        }
    }
};
    
class Kvadrat: public Rectangle
{
    
};
int main()
{
    int option, option2, option3;
    while (true){
        cout << "\nВыберите фигуру\n" << "1.Прямоугольник \n" << "2.Квадрат \n"<<"3.Выход из программы" << endl;
        cin >> option;
        switch (option){ 
            case 1:
            Rectangle Rectangle;
            Rectangle.SetSides();
            while (true){
                cout << "\nВыберите действие\n" << "1.Найти периметр \n" << "2.Найти площадь\n" << "3.Возвращение к выбору фигуры" << endl;
                cin >> option2;
                switch (option2){
                    case 1:
            Rectangle.GetPerimeter();
            break;
            case 2:
            Rectangle.GetSquare();
            break;
            case 3:
            return 0;
break;
                }
            }
        break;
        case 2:
        Rectangle.SetSides();
        while (true){
        cout << "\nВыберите действие\n" << "1.Найти периметр \n" << "2.Найти площадь\n" << "3.Возвращение к выбору фигуры" << endl;
        cin >> option3;
        switch(option3){
            case 1:
            Rectangle.GetPerimeter1();
            break;
            case 2:
            Rectangle.GetSquare1();
            break;
            case 3:
            return 0;
        }
        }
        break;
        case 3:
        return 0;
        break;
    }
    }
    return 0;
}
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
23.10.2022, 18:06
Лучший ответ Сообщение было отмечено Suppas15 как решение

Решение

Цитата Сообщение от Suppas15 Посмотреть сообщение
class Quad
Этот класс описывает, простите, что? Квадрат? А там ниже класс Kvadrat описывает тогда что?
Повторюсь, ваша иерархия неверна, потому что ваши классы ведут себя по-разному, но раз уж вы собираетесь это сделать, то:

Наследование должно идти по пути "является и ведет себя как".
Например, квадрат является прямоугольником. Значит наследуем квадрат от прямоугольника: class Square : public Rectangle
Четырёхугольник является квадратом? Нет. Некоторые четырёхугольники не являются квадратами. Не наследуем от квадрата четырёхугольника.
Прямоугольник является четырёхугольником. Значит наследуем прямоугольник от четырехугольника. class Rectangle: public Quadrilateral
Квадрат будет опосредовано унаследован от четырехугольника. Через прямоугольник.

Цитата Сообщение от Suppas15 Посмотреть сообщение
void SetSides()
    {
        cout << "Введите значения сторон фигуры (Длину a и ширину b, через пробел)";
        cin >> a;
        cin >> b;
    }
Не надо так делать. Получите тройбан и будет обидно.
Сущность должна быть отделена от операций с сущностью и её методы не должны делать побочных эффектов.
Цитата Сообщение от Suppas15 Посмотреть сообщение
public:
    float a,b;
У вас на ООП же задание?
В ООП есть такая штука -- инкапсуляция называется.
Это, грубо говоря, сокрытие данных за интерфейсом класса.
Поля класса уберите в блок private, в блоке public сделайте методы для доступа к этим данным.

Цитата Сообщение от Suppas15 Посмотреть сообщение
Функции вычисления площади
Это вот хорошая демонстрация того, почему наследование прямоугольника от четырёхугольника некорректно.
Для вычисления площади прямоугольника недостаточно длин сторон. Нужно ещё что-то. Диагональ там например.
Что избыточно для прямоугольника и квадрата.

Цитата Сообщение от Suppas15 Посмотреть сообщение
1) Как сделать так, чтобы он в меню реально возвращался к выбору фигуры, а не завершал всю программу через return 0? (лучшего не придумал)
Зачем вы тратите время на то, чего нет в задании? По-приколу? )

Цитата Сообщение от Suppas15 Посмотреть сообщение
2)Как сделать функции виртуальными? Не нашёл родительских функций (скорее всего, у меня их и нет)
У вас их и нет.

Цитата Сообщение от Suppas15 Посмотреть сообщение
3)Где тут вообще можно "вставить" деструкторы и конструкторы (не по умолчанию), или можно без них?
Можно (и нужно) сделать конструктор для инициализации полей значениями.
Деструктор можно задекларировать явно и нужно сделать виртуальным.

Добавлено через 23 минуты
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <iostream>
 
// четырёхугольник лежит в основе иерархии
class Quadrilateral {
public:
    // конструктор с параметрами, инициализирующий данные класса
    Quadrilateral(float a, float b, float c, float d)
    // это вот называется "списки инициализации", тут указывается какие поля класса чем будут инициализироваться
            : a(a), b(b), c(c), d(d) {}
 
    // виртуальный деструктор с реализацией по-умолчанию (ничего не делает)
    virtual ~Quadrilateral() = default;
 
    // следующие четыре функции -- для получения значений полей классов
    // const на конце функции означает, что функция не менят полей класса
    float getA() const {
        return a;
    }
 
    float getB() const {
        return b;
    }
 
    float getC() const {
        return c;
    }
 
    float getD() const {
        return d;
    }
 
    // виртуальная функция получения периметра четырёхугольника
    virtual float getPerimeter() const {
        return a + b + c + d;
    }
 
private:
    // сокрытые поля класса
    float a, b, c, d;
};
 
// так как прямоугольник является четырехугольником, наследуем прямоугольник от четырёхугольника
class Rectangle : public Quadrilateral {
public:
    // прямоугольник можно инициализировать двумя сторонами
    Rectangle(float a, float b)
    // вызов конструктора родительсого класса
    // прямоугольник это квадрат с попарно равными сторонами (между которыми угол 90%, но это мы опустим)
            : Quadrilateral(a, b, a, b) {}
 
    // деструктор не нужен, он будет унаследован от четырёхугольника
    // но можно написать, если очень хочется:
    //~Rectangle() override = default;
 
    // метод расчёта периметра тоже не нужен, он будет унаследован от четырёхугольника и
    // будет правильно рассчитывать периметр, так как наш прямоугольник является четырехугольником
    // но если очень хочется, можно явно обозначить:
    //float getPerimeter() const override {
    //    return Quadrilateral::getPerimeter();
    //}
};
 
// квадрат наследуется от прямоугольника, потому что квадрат является прямоугольником
class Square : public Rectangle {
public:
    // для создания квадрата достаточно знать одну сторону
    Square(float side)
    // вызов конструктора родительсого класса
    // квадрат это прямоугольник с равными сторонами
            : Rectangle(side, side) {}
 
    // деструктор не нужен, он будет унаследован от четырёхугольника
    // но можно написать, если очень хочется:
    //~Square() override = default;
 
    // метод расчёта периметра тоже не нужен, он будет унаследован от четырёхугольника и
    // будет правильно рассчитывать периметр, так как наш прямоугольник является четырехугольником
    // но если очень хочется, можно явно обозначить:
    //float getPerimeter() const override {
    //    return Rectangle::getPerimeter();
    //}
};
 
// теперь можно отдельно описать функции для вывода получившейся кашицы
 
// мне, например, нравится писать в виде перегрузки операторов вывода
// тогда можно будет прямо отправлять объекты в потоки вывода
 
// оператор вывода в поток для класса четырёхугольника
std::ostream &operator<<(std::ostream &out, const Quadrilateral &s) {
    return out << "Quadrilateral{"
               << "a=" << s.getA() << ", "
               << "b=" << s.getB() << ", "
               << "c=" << s.getC() << ", "
               << "d=" << s.getD() << "}";
}
 
// остальные можно не писать, тогда для унаследованных будет использоваться вывод четырёхугольника
 
// для прямоугольника
std::ostream &operator<<(std::ostream &out, const Rectangle &s) {
    return out << "Rectangle{"
               << "a=" << s.getA() << ", "
               << "b=" << s.getB() << ", "
               << "c=" << s.getC() << ", "
               << "d=" << s.getD() << "}";
}
 
// для квадрата
std::ostream &operator<<(std::ostream &out, const Square &s) {
    return out << "Square{"
               << "a=" << s.getA() << ", "
               << "b=" << s.getB() << ", "
               << "c=" << s.getC() << ", "
               << "d=" << s.getD() << "}";
}
 
// так же можно сделать операторы ввода для классов:
 
std::istream &operator>>(std::istream &in, Quadrilateral &q) {
    float a, b, c, d; // стороны
    in >> a >> b >> c >> d; // вводим
    q = Quadrilateral(a, b, c, d); // с помощью неявного опреатора присваивания копируем данные в переданную переменную
    return in;
}
 
std::istream &operator>>(std::istream &in, Rectangle &r) {
    float a, b; // стороны
    in >> a >> b; // вводим
    r = Rectangle(a, b); // с помощью неявного опреатора присваивания копируем данные в переданную переменную
    return in;
}
 
std::istream &operator>>(std::istream &in, Square &r) {
    float a; // сторона
    in >> a; // вводим
    r = Square(r); // с помощью неявного опреатора присваивания копируем данные в переданную переменную
    return in;
}
 
int main() {
 
    // создание четырёхугольника
    Quadrilateral quadrilateral(2, 3, 4, 5);
    // создание прямоугольника
    Rectangle rectangle(3, 5);
    // создание квадрата
    Square square(7);
 
    // использование операторов вывода
    std::cout << quadrilateral << "\n"
        << rectangle << "\n"
        << square << "\n";
 
    // использование операторов ввода
    std::cin >> quadrilateral >> rectangle >> square;
 
    std::cout << quadrilateral << "\n"
              << rectangle << "\n"
              << square << "\n";
 
    return 0;
}
1
6 / 5 / 1
Регистрация: 04.04.2022
Сообщений: 85
25.10.2022, 20:12  [ТС]
lemegeton, Начиная с 86 строки ничего не понял (да и до неё сложновато), ибо не изучал такое никогда. Эту "перегрузку" операторов вывода можно как-то заменить? Чтобы можно было вводить значения с клавиатуры и меню удобно составить через switch?
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
25.10.2022, 22:25
Перегруженный оператор это просто функция, которая позволяет использовать в её в качестве оператора.

То бишь вот это
C++
1
    std::cin >> quadrilateral >> rectangle >> square;
То же самое, что вот это (есть небольшая разница, но несущественная):
C++
1
2
3
    operator>>(std::cin, quadrilateral);
    operator>>(std::cin, rectangle);
    operator>>(std::cin, square);
То есть просто вызов функции с таким вот именем.

Цитата Сообщение от Suppas15 Посмотреть сообщение
Эту "перегрузку" операторов вывода можно как-то заменить?
Конечно. Просто назовите функцию по-другому и вызовите, как я выше показал.
Потому что если она не будет таким вот специальным образом называться, её нельзя будет использовать в качестве оператора.

Добавлено через 33 секунды
Цитата Сообщение от Suppas15 Посмотреть сообщение
Чтобы можно было вводить значения с клавиатуры и меню удобно составить через switch?
Я вот в это вот не умею и не хочу уметь, поэтому я не понял, что это такое.

Добавлено через 4 минуты
Цитата Сообщение от Suppas15 Посмотреть сообщение
ибо не изучал такое никогда
Быстрее будет "изучить", чем переписать.
Концепция простейшая.
Да и в интернете полно статей про перегрузку операторов (в данном случае ввода и вывода).
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.10.2022, 22:25
Помогаю со студенческими работами здесь

Дано N четырехугольников и M квадратов, найти четырехугольники с минимальной и максимальной площадью и номера одинаковых
Помогите доделать.Дано N четырехугольников и M квадратов, найти четырехугольники с минимальной и максимальной площадью и номера одинаковых...

Создать иерархию классов для хранения четырехугольников
Задание:Создать иерархию классов для хранения &quot;четырехугольников&quot;. Реализовать возможность проверки типа &quot;четырехугольника&quot;. Для...

Создать класс Integral, в котором реализовано вычисление определенного интеграла методом прямоугольников, методом трапец
Должны быть реализованы безаргументные и инициализирующие конструкторы, в том числе конструктор с двумя аргументами – итераторами,...

Вводятся координаты N прямоугольников; определить, сколько среди них квадратов
Процедура определяет,яв-ся ли прямоугольник квадратом. Вводятся координаты N прямоугольников. Определить,сколько среди них квадратов....

Создать класс колесо, имеющее радиус. Определить конструкторы. Создать класс машин, содержащий класс колесо
Создать класс колесо, имеющее радиус. Определить конструкторы. Создать класс машин, содержащий класс колесо. Дополнительно есть марка,...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
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-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru