Форум программистов, компьютерный форум, киберфорум
ООП и паттерны
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Wanna be serious
 Аватар для Bespridelschic
587 / 474 / 186
Регистрация: 31.07.2013
Сообщений: 1,693

На сколько соответствует код концепции ООП

19.12.2015, 06:00. Показов 1109. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток форумчане. Я понимаю что вопрос может звучать глупо, но мне это важно знать.

Суть вопроса вот в чем. Есть стандартное задание: описать класс Student. Я в общем так и сделал, и подкрутил ещё пару контекстных действий для работы с некой базов данных. Но теперь возник вопрос, на сколько код соответствует концепции ООП? Не написал ли я программу в виде "процедурное программирование в классах"? И если это так, то на сколько идёт перекос в сторону ООП или в сторону процедурного программирования? Заранее спасибо всем откликнувшимся

Код

Main.cpp
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
#include <iostream>
#include <vector>
#include <string>
#include "Student.h"
#include "Check.h"
#include "Select.h"
 
int main() {
    setlocale(LC_ALL, "Russian");
    system("Title Students");
    {
        std::cout << "Введите количество студентов: ";
        int n;
        Check::Input_data(n);
        std::cout
            << "Создано "
            << n
            << " студентов, введите информацию:\n"
            << std::endl;
        std::vector<Student> student(n);
        for (int i = 0; i < n; i++)
        {
            std::cout << "Студент №" << i + 1 << ":\n";
            student[i].Input_data();
        }
        for (int i = 0; i < n; i++)
        {
            std::cout << "Студент №" << i + 1 << ":\n";
            student[i].Show_info();
        }
        bool b = true;
        while (b)
        {
            Select::Selection(b, student, n);
        }
    }
    system("Pause >> 0");
    system("cls");
    std::cout << "Программа завершает свою работу. ";
    system("Pause");
    return 0;
}

Student.cpp
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
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include "Student.h"
#include "Check.h"
 
Student::Student() {
    Name = Last_Name = "No data";
    age = course = number = average = 0;
    marks = { 0 };
}
 
Student::~Student() {
    std::cout << "Студент с именем " << Name << " был удалён\n";
}
 
void Student::Input_data() {
    std::cout << "Введите имя: ";
    std::cin >> Name;
    std::cout << "Введите фамилию: ";
    std::cin >> Last_Name;
    std::cout << "Введите возраст: ";
    Check::Input_data(age);
    std::cout << "Введите курс: ";
    Check::Input_data(course);
    std::cout << "Введите количество оценок: ";
    Check::Input_data(number);
    std::cout << "Введите " << number << " оценок:\n";
    marks.resize(number);
    for (int i = 0; i < number; i++)
    {
        std::cout << "Оценка " << i+1 << ": ";
        int n;
        Check::Input_marks(n);
        marks[i] = n;
    }
    for (int i = 0; i < number; i++)
    {
        average += marks[i];
    }
    average /= number;
    std::cout << std::endl << std::endl;
}
 
Student Student::operator += (const Student &t) const
{
    Student average_sum, average_local;
    for (int i = 0; i < t.number; i++)
    {
        average_local.average = t.marks[i];
    }
    average_local.average /= t.number;
    return average_local + average_sum;
}
 
Student Student::operator + (const Student &t) const
{
    Student average_sum;
    average_sum.average = average + t.average;
    return average_sum;
}
 
Student Student::operator -= (const Student &t) const
{
    Student average_sum;
    average_sum.average = average - t.average;
    return average_sum;
}
 
Student Student::operator - (const Student &t) const
{
    Student average_sum;
    average_sum.average = average - t.average;
    return average_sum;
}
 
void Student::Show_info() const {
    std::cout
        << "Имя: " << Name << std::endl
        << "Фамилия: " << Last_Name << std::endl
        << "Возраст: " << age << std::endl
        << "Курс: " << course << std::endl
        << "Оценки: ";
    for (int i = 0; i < number; i++)
    {
        std::cout << std::setw(3) << marks[i];
    }
    std::cout << std::endl << std::endl;
}
 
void Student::Show_average()
{
    for (int i = 0; i < number; i++)
    {
        average += marks[i];
    }
    average /= number;
    std::cout << "Средний балл студента = " << average << std::endl;
}
 
void Student::Show_global_average(int n)
{
    average /= n;
    std::cout << "Средний бал = " << average << std::endl;
}

Student.h
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
#pragma once
#ifndef STUDENT_H_
#define STUDENT_H_
 
#include <string>
#include <vector>
 
class Student {
private:
    std::string Name, Last_Name;
    int age, course, number;
    double average;
    std::vector<int> marks;
public:
    Student();
    ~Student();
    void Input_data();
    Student operator += (const Student &t) const;
    Student operator + (const Student &t) const;
    Student operator -= (const Student &t) const;
    Student operator - (const Student &t) const;
    void Show_info() const;
    void Show_average();
    void Show_global_average(int n);
};
 
#endif

Check.cpp
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
#include <iostream>
#include "Check.h"
 
int Check::Input_number(int &n)
{
    while (true)
    {
        std::cin >> n;
        if (!(std::cin))
        {
            std::cin.clear();
            std::cerr << "Встречен запрещенный символ, попробуйте снова: ";
            while (std::cin.get() != '\n')
            {
                continue;
            }
        }
        else
        {
            break;
        }
    }
    return n;
}
 
int Check::Input_data(int &n)
{
    while (true)
    {
        Check::Input_number(n);
        if (n < 1)
        {
            std::cin.clear();
            std::cerr << "Ошибка! Число не может быть меньше 1, попробуйте снова: ";
            while (std::cin.get() != '\n')
            {
                continue;
            }
        }
        else
        {
            return n;
        }
    }
}
 
int Check::Input_marks(int &n)
{
    while (true)
    {
        Check::Input_data(n);
        if (n > 5)
        {
            std::cin.clear();
            std::cerr << "Ошибка! Число не может быть больше 5, попробуйте снова: ";
            while (std::cin.get() != '\n')
            {
                continue;
            }
        }
        else
        {
            return n;
        }
    }
}
 
int Check::Input_number_of_student(int &n, int number)
{
    while (true)
    {
        Check::Input_data(n);
        if (n > number)
        {
            std::cin.clear();
            std::cerr << "Ошибка! Число студентов превышено, попробуйте снова: ";
            while (std::cin.get() != '\n')
            {
                continue;
            }
        }
        else
        {
            return n;
        }
    }
}

Check.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
#ifndef CHECK_H_
#define CHECK_H_
 
#include <iostream>
#include <string>
 
class Check {
public:
    static int Input_data(int &n);
    static int Input_number(int &n);
    static int Input_marks(int &n);
    static int Input_number_of_student(int &n, int number);
};
 
#endif

Select.cpp
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
#include <iostream>
#include <vector>
#include "Student.h"
#include "Select.h"
#include "Check.h"
 
void Select::Show_text()
{
    std::cout
        << "\nВведите число для проведения операции с информацией:\n"
        << "1. Показать информацию о студенте\n"
        << "2. Показать информацию по всем студентам\n"
        << "3. Изменить информацию о студенте\n"
        << "4. Добавить нового студента\n"
        << "5. Удалить информацию о студенте\n"
        << "6. Показать информацию о среднем балле студента\n"
        << "7. Показать средний бал всех студентов\n"
        << "8. Очистить экран\n"
        << "9. Завершить работу с программой\n\n"
        << "Введите необходимое число для проведения операции: ";
}
 
void Select::Selection(bool &b, std::vector<Student> &student, int &number)
{
    Select::Show_text();
    int n;
    Check::Input_data(n);
    switch (n)
    {
    case 1:
    {
        Select::Number1(student);
        system("Pause");
        break;
    }
    case 2:
    {
        Select::Number2(student, number);
        system("Pause");
        break;
    }
    case 3:
    {
        Select::Number3(student, number);
        system("Pause");
        break;
    }
    case 4:
    {
        Select::Number4(student, number);
        system("Pause");
        break;
    }
    case 5:
    {
        Select::Number5(student, number);
        system("Pause");
        break;
    }
    case 6:
    {
        Select::Number6(student, number);
        system("Pause");
        break;
    }
    case 7:
    {
        Select::Number7(student, number);
        system("Pause");
        break;
    }
    case 8:
    {
        system("cls");
        break;
    }
    case 9:
    {
        Select::Exit(b);
        break;
    }
    default:
    {
        std::cerr << "Ошибка! Не найдено совпадений, попробуйте снова...\n";
        break;
    }
    }
}
 
void Select::Number1(std::vector<Student> &student)
{
    std::cout << "Введите номер студента информация которого вам требуется: ";
    int i;
    Check::Input_data(i);
    i--;
    std::cout << std::endl;
    student[i].Show_info();
}
 
void Select::Number2(std::vector<Student> &student, int &number)
{
    for (int i = 0; i < number; i++)
    {
        student[i].Show_info();
    }
}
 
void Select::Number3(std::vector<Student> &student, int &number)
{
    std::cout << "Введите номер студента подлежащего изменению: ";
    int i;
    Check::Input_number_of_student(i, number);
    i--;
    student[i].Input_data();
}
 
void Select::Number4(std::vector<Student> &student, int &number)
{
    number++;
    student.resize(number);
    student[number - 1].Input_data();
}
 
void Select::Number5(std::vector<Student> &student, int &number)
{
    std::cout << "Введите номер студента подлежащего удалению: ";
    int i;
    Check::Input_number_of_student(i, number);
    i--;
    number--;
    student.erase(student.begin() + i);
}
 
void Select::Number6(std::vector<Student> &student, int &number)
{
    std::cout << "Введите номер студента подлежащего изменению: ";
    int i;
    Check::Input_number_of_student(i, number);
    i--;
    student[i].Show_average();
    std::cout << std::endl;
}
 
void Select::Number7(std::vector<Student> &student, int &number)
{
    Student total_average;
    for (int i = 0; i < number; i++)
    {
        total_average += student[i];
    }
    total_average.Show_global_average(number);
}
 
bool Select::Exit(bool &b)
{
    return b = false;
}

Select.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#ifndef SELECT_H_
#define SELECT_H_
 
#include <vector>
 
class Select {
public:
    static void Show_text();
    static void Selection(bool &b, std::vector<Student> &student, int &number);
    static void Number1(std::vector<Student> &student);
    static void Number2(std::vector<Student> &student, int &number);
    static void Number3(std::vector<Student> &student, int &number);
    static void Number4(std::vector<Student> &student, int &number);
    static void Number5(std::vector<Student> &student, int &number);
    static void Number6(std::vector<Student> &student, int &number);
    static void Number7(std::vector<Student> &student, int &number);
    static bool Exit(bool &b);
};
 
#endif

0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.12.2015, 06:00
Ответы с готовыми решениями:

Концепции ООП
Товарищи, помогите. Пользоваться гуглом не умею судя по всему. Я знаю такие концепции ООП как инкапсуляция, наследование, полиморфизм....

На сколько приведенный код неправильный с точки зрения ООП?
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; ...

Соответствует ли код стандарту?
Привет! Имеется следующий код (в очень урощенном виде) struct foo {}; int main() { struct foo {}; void f() throw...

14
542 / 163 / 79
Регистрация: 23.09.2013
Сообщений: 316
19.12.2015, 07:18
Bespridelschic, чтож, для того чтобы формально ответить на данный вопрос, обратимся к википедии:
ООП:
Необходимо обратить внимание на следующие важные части этого определения: 1) объектно-ориентированное программирование использует в качестве основных логических конструктивных элементов объекты, а не алгоритмы; 2) каждый объект является экземпляром определенного класса; 3) классы образуют иерархии. Программа считается объектно-ориентированной, только если выполнены все три указанных требования. В частности, программирование, не использующее наследование, называется не объектно-ориентированным, а программированием с помощью абстрактных типов данных.
Если исходить из этого определения, Ваш код не соответствует концепции ООП. (наследования у Вас в программе нет, экземпляры некоторых объектов и вовсе не создаются) В лучшем случае можно было бы причислить Вашу программу к использующим АТД.

Ваши слова
Не написал ли я программу в виде "процедурное программирование в классах"?
вполне могут быть употреблены в качестве поверхностного описания того, что происходит. Насколько идет перекос в сторону функционального стиля программирования? Ну собственно говоря только класс Студент и можно выделить в качестве полноценного класса, да и то с наличием избыточного функционала в своём составе. Весь остальной код представляет из себя чисто функциональный стиль, с аккуратным раскидыванием функций в виде статических методов по двум классам.

В ООП каждый класс рассматриваемый в контексте использования предполагает определенную смысловую нагрузку. Это некоторый набор данных и методов по работе с ними, которые были объединены в одну согласованную сущность. Сокрытие данных от прямого изменения в сочетании с методами - позволяет инкапсулировать две вещи - способ представления данных (внутри класса мы вольны изменять представление как нам вздумается) и алгоритмы обработки данных (внутри класса мы можем изменять реализацию методов при этом вызывающая сторона этого не должна замечать). В целом это наделяет классы важным и полезным свойством - за счет инкапсуляции достигается возможность скрыть сложность и конкретику реализации за границами класса - его публичным интерфейсом. И во вне работать с объектами класса как с согласованной абстракцией. (У С. Макконела в книге Совершенный Код на эту тему приводится характерный пример - инкапсуляция позволяет представить огромный особняк в виде простого, абстрактного чертежа здания - с крышей, стенами, дверью и трубой, при этом не позволяя стороне, которая использует наш упрощенный домик - увидеть а из чего сделана дверь, а из какого материала у двери ручка и т.д.) При этом за этой абстракцией - скрыта вся сложность реального здания. Полиморфизм приносит возможность расширения единственной абстракции на целое множество - за счет полиморфного изменения поведения в зависимости от того, какой наследник реально был создан. Наследование, особенно в с++ жестко завязано с полиморфизмом на уровне классов (если не брать в расчет указатели на функции - единственный способ получить полиморфное поведение - наследование от класса с виртуальным методом. Кроме того наследование - позволяет расширять существовавшее поведение класса, добавляя дополнительные свойства и повышая тем самым универсальность без дублирования кода (наследование реализации).

Про ООП написаны целые книги, я не хотел бы тут их целиком переписывать, в чем основная мысль, применительно к Вашей программе? В том, что всего этого могучего механизма при помощи которого люди научились создавать сложнейшие системы в Вашем коде не используется. Я попробую выделить несколько концепций, которые могли бы быть реализованы для приближения кода к ООП стилю. То что творится в мейне - могло быть выделено в отдельный класс программы, который в конструкторе принимал бы все необходимые ресурсы для настройки и у которого был бы единственный метод - Execute, в main осталось бы создание конкретных объектов, передача их в Programm и вызов метода Execute. Если посмотреть на Ваше общение с пользователем (Ваша программа использует интерфейс командной строки) - а кроме командной строки могло быть получение информации из графического интерфейса пользователя, могло быть получение данных от клиента по сети, могла быть автономная работа с получением данных из файла скрипта (например для интеграционного теста по сценарию) - таким образом мог быть сделан класс (абстрактный, образующий интерфейс с методами без реализации - который позволял бы отображать некоторые сообщения, запрашивать ответы от пользователя, соответственно мог быть создан класс - реализация, который осуществлял бы общение через потоки (заметьте не через конкретные cin и cout, а через потоки вообще) который бы получал в качестве аргументов конструктора конкретные потоки, которые нужно использовать. (Во всех других местах программы никаких прямых вызовов cin и cout не осталось бы). Можно было бы создать класс меню, в который можно было бы регистрировать пункты меню (объекты еще одного класса) и который бы умел их отображать в средство отображения с демонстрацией текста меню и номера в списке. В зависимости от выбранного пользователем варианта - меню бы вызывало из зарегистрированного объекта - команду (см. шаблон команда).
Из студента должны были бы уйти все вычисления связанные с обработкой статистики студентов (ваши Show_) - для их реализации создан был бы отдельный класс подсчета статистики. Возможно стоило бы создать еще и класс факультета или вуза, для обработки коллекций студентов.

Это разбиение я выполнил исходя из 1) возможности разнообразного использования программы в разных контекстах (выделение классов вывода и получения значений от пользователя) 2) мыслей об универсальности элементов и их повторного использования (класс меню с возможностью динамического расширения) 3) Мысли о сущностях реального мира (Студент, Факультет, Статистика) Как можно было бы дополнительно удостовериться в правильности разбиения? Во-первых можно попытаться проанализировать, соответствуют ли классы в программе принципам SOLID и во-вторых, можно было бы разрабатывать программу в методологии TDD , задаваясь вопросом - а как я смогу извне проверить тот или иной фрагмент кода, что является существенным поведением, а что деталью реализации и представления.
ООП в целом и его реалии в с++ в частности - громадная и интереснейшая тема, освоив которую программист становится способен создавать по-настоящему гибкие, расширяемые и модульные программы, надеюсь Ваше стремление к его освоению не угаснет перед лицом трудностей на пути. А соответственно и моё длиннющее сообщение не окажется написанным зря.
2
Wanna be serious
 Аватар для Bespridelschic
587 / 474 / 186
Регистрация: 31.07.2013
Сообщений: 1,693
19.12.2015, 08:52  [ТС]
Melg, спасибо вам огромное за столь развернутый ответ. Я учту свои ошибки, и буду обращаться к вашему ответу при дальнейшем изучении C++, для более точного понимания.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
19.12.2015, 13:07
Цитата Сообщение от Melg Посмотреть сообщение
Если исходить из этого определения, Ваш код не соответствует концепции ООП. (наследования у Вас в программе нет, экземпляры некоторых объектов и вовсе не создаются) В лучшем случае можно было бы причислить Вашу программу к использующим АТД.
более идиотского определения ооп не доводилось ещй встречать.
дальше не читал.

Цитата Сообщение от Bespridelschic Посмотреть сообщение
на сколько код соответствует концепции ООП?
оо-программирование - стиль программирования использующий оо-парадигму в качестве своей основы.

парадигма - система взглядов и способов абстрагирования.

оо-парадигма - парадигма, при которой программист может рассматривать конструкции на языке,
как сущности, наделенные свойствами и умениями.

пример:

C++
1
2
3
4
5
        for (int i = 0; i < n; i++)
        {
            std::cout << "Студент №" << i + 1 << ":\n";
            student[i].Show_info();
        }
можете ли вы рассматривать студента, как некий механизм:
сущность наделенную свойствами и умениями?

вот он умеет например, показать инфу о себе.

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

а сам код написан так,
что у вас есть такая возможность.


что касается наследований/полиморфизмов - все это очень здорово,
и является признаками "развитого ооп".
но не являются необходимостью для оо-программирования.
1
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
19.12.2015, 13:33
Цитата Сообщение от Melg Посмотреть сообщение
Весь остальной код представляет из себя чисто функциональный стиль, с аккуратным раскидыванием функций в виде статических методов по двум классам.
Осторожнее с терминами: процедурное и функциональное программирование — разные вещи.

Bespridelschic, безотносительно парадигм к коду есть как минимум пара серьезных замечаний.

1. Бо́льшая часть классов содержит исключительно статические методы. Значит, в этих случаях классы как таковые не нужны. Хватило бы функций, объединенных в пространстве имен.

2. В класс Student жестко зашит весь ввод-вывод, что сильно ограничивает возможности его использования. В реальной системе данные для объекта могут прийти из множества источников: файлы, сеть, база данных. Аналогично и с выводом. Следовательно, взаимодействие с внешним миром лучше выносить отдельно.

PS Уже после написания я увидел, что на это указывали во втором посте. Но в посте такого объема суть теряется.
1
Wanna be serious
 Аватар для Bespridelschic
587 / 474 / 186
Регистрация: 31.07.2013
Сообщений: 1,693
19.12.2015, 13:43  [ТС]
0x10, спасибо за разъяснения. Я пока что учусь всему этому, а пока учусь - стараюсь отработать полученные знания в каких-нибудь более менее полезные программах.
0
15 / 15 / 1
Регистрация: 26.01.2015
Сообщений: 82
13.01.2016, 10:36
Я не увидел у тебя реализации инкапсуляция, скрытие свойств, в учебниках говориться что в ООП обращение
к свойствам идет через сеттеры и геттеры, чтобы защитить данные извне.
0
Wanna be serious
 Аватар для Bespridelschic
587 / 474 / 186
Регистрация: 31.07.2013
Сообщений: 1,693
13.01.2016, 10:41  [ТС]
Цитата Сообщение от ShkrylAndrei Посмотреть сообщение
Я не увидел у тебя реализации инкапсуляция, скрытие свойств, в учебниках говориться что в ООП обращение
к свойствам идет через сеттеры и геттеры, чтобы защитить данные извне.
Про геттеры и сеттеры я пока только слышал. В будущем думаю доберусь до этой темы.
0
15 / 15 / 1
Регистрация: 26.01.2015
Сообщений: 82
13.01.2016, 10:51
Там все очень просто, вот твой класс
C++
1
2
3
4
5
6
class Student {
private:
    std::string Name, Last_Name;
    int age, course, number;
    double average;
    std::vector<int> marks;
у тебя объявлены поля как "Private" то есть они скрыты от изменения извне, теперь тебе надо сделать несколько
public методов, меняющие поведение этих свойст, т.е. будет
public set_age(int age)
{
this.age=age;
}
public get_age()
{
return this.age
}

...
0
Wanna be serious
 Аватар для Bespridelschic
587 / 474 / 186
Регистрация: 31.07.2013
Сообщений: 1,693
13.01.2016, 10:55  [ТС]
ShkrylAndrei, подходит ли перегруженная operator >> () по сеттер, и перегруженная operator << () под геттер?
0
Модератор
Эксперт функциональных языков программирования
3136 / 2283 / 469
Регистрация: 26.03.2015
Сообщений: 8,886
13.01.2016, 16:23
Цитата Сообщение от Bespridelschic Посмотреть сообщение
ShkrylAndrei, подходит ли перегруженная operator >> () по сеттер, и перегруженная operator << () под геттер?
Нет
0
Wanna be serious
 Аватар для Bespridelschic
587 / 474 / 186
Регистрация: 31.07.2013
Сообщений: 1,693
13.01.2016, 16:38  [ТС]
Shamil1, В таком случае, не могли бы вы продемонстрировать как в моём случае применить сеттеры/геттеры, на основании кода приёма/вывода данных (т.е. ввод всей необходимой для объекта информации)?
operator >> ()
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
std::istream & operator >> (std::istream & is, Student & t)
{
    std::cout << "Введите имя: ";
    is >> t.Name;
    std::cout << "Введите фамилию: ";
    is >> t.Last_Name;
    std::cout << "Введите возраст: ";
    Check::Input_data(t.age);
    std::cout << "Введите курс: ";
    Check::Input_data(t.course);
    std::cout << "Введите количество оценок: ";
    Check::Input_data(t.number);
    std::cout << "Введите " << t.number << " оценок:\n";
    t.marks.resize(t.number);
    for (int i = 0; i < t.number; i++)
    {
        std::cout << "Оценка " << i + 1 << ": ";
        int n;
        Check::Input_marks(n);
        t.marks[i] = n;
    }
    for (int i = 0; i < t.number; i++)
    {
        t.average += t.marks[i];
    }
    t.average /= t.number;
    std::cout << std::endl;
    return is;
}

operator << ()
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::ostream & operator << (std::ostream &os, const Student &t)
{
    os
        << "Имя: " << t.Name << std::endl
        << "Фамилия: " << t.Last_Name << std::endl
        << "Возраст: " << t.age << std::endl
        << "Курс: " << t.course << std::endl
        << "Оценки: ";
    for (int i = 0; i < t.number; i++)
    {
        os << std::setw(3) << t.marks[i];
    }
    os
        << std::endl << "Средний бал: " << t.average
        << std::endl << std::endl;
    return os;
}
0
Модератор
Эксперт функциональных языков программирования
3136 / 2283 / 469
Регистрация: 26.03.2015
Сообщений: 8,886
13.01.2016, 17:19
C++
1
os << "Имя: " << t.get_Name() << std::endl;
И так далее
0
Wanna be serious
 Аватар для Bespridelschic
587 / 474 / 186
Регистрация: 31.07.2013
Сообщений: 1,693
13.01.2016, 17:23  [ТС]
Shamil1, т.е. в методах для каждого поля класса должен быть прописан свой сеттер/геттер? Прошу прощения если я задаю чересчур много вопросов, просто хочу разобраться с этим всем.
0
Модератор
Эксперт функциональных языков программирования
3136 / 2283 / 469
Регистрация: 26.03.2015
Сообщений: 8,886
13.01.2016, 18:35
Цитата Сообщение от Bespridelschic Посмотреть сообщение
т.е. в методах для каждого поля класса должен быть прописан свой сеттер/геттер? Прошу прощения если я задаю чересчур много вопросов, просто хочу разобраться с этим всем.
Обычно геттеры и/или сеттеры добавляют для полей:
1. К которым нужен доступ из вне (на чтение и/или запись)
2. Доступ только "изнутри", но, например, есть какие-то условия, которые нужно проверять при каждом обращении (например, при записи Возраст проверять, что он не отрицательный)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.01.2016, 18:35
Помогаю со студенческими работами здесь

Точно ли код соответствует условию задачи?
1. Создайте командный файл, работающий с двумя параметрами и выполняющий следующие действия без вывода на экран монитора командных строк:...

Соответствует ли код условиям задачи (внутри)?
Задача: Напишите программу, в которой есть базовый класс с открытым целочисленным полем. В классе описан виртуальный индексатор,...

Средний радиус яйца домашней курицы 5 см, а инкубаторной – 4 см. Сколько инкубаторных яиц соответствует де
Средний радиус яйца домашней курицы 5 см, а инкубаторной – 4 см. Сколько инкубаторных яиц соответствует десятку домашних? Сколько...

Исходный код, который соответствует ассемблерному коду
foot1: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax sall $4, %eax subl 8(%ebp), %eax movl %ebp, %esp popl %ebp ret

Средний радиус яйца домашней курицы 5 см, а инкубаторной – 4 см. Сколько инкубаторных яиц соответствует десятку домашних?
Средний радиус яйца домашней курицы 5 см, а инкубаторной – 4 см. Сколько инкубаторных яиц соответствует десятку домашних? Сколько...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
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 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru