Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337

Работа с абстрактным классом, считывание данных

21.03.2019, 12:05. Показов 2636. Ответов 41
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, уважаемые форумчане! Пишу программу по следующему заданию:

Создать класс Изготовитель cо следующими полями:
- торговая марка;
- страна происхождения.
Создать базовый класс Часы (модель, изготовитель) и дочерние классы:
- механические часы (продолжительность работы, гарантийный срок);
- электронные часы (тип батареи, тип экрана);
- использовать класс Изготовитель как поле класса Часы.
Функции:
- cчитать из текстового файла данные о разных часах;
- используя механизм виртуальных функций, в новый файл записать информацию о часах, отсортированных по названию марки;
- подсчитать количество часов указанного изготовителя с заданным типом батареи;
- вывести информацию о механических часах с самым большим гарантийным сроком.

Поля для Механические часы: string string string int int
Поля для Электронные часы: string string string string string

Важно, что поля для 4 и 5 записи различаются.

Так как у меня не очень большой опыт работы с классами, у меня возникли следующие вопросы:

1. Как для данной задачи считывать данные? Нужен ли дополнительный класс для считывания? Если нет, то как различать данные по последним 4 и 5 полям (они различаются). В какой объект считывать данные?

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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>
 
    using namespace std;
       
class Producer { //Класс Изготовитель (этот класс используется внутри другого класса Часы (композиция объектов))
 
    public:
 
        string t_mark; //Торговая марка
        string c_origin; //Страна происхождения
};
 
class Clock { //Базовый, абстрактный класс Часы
 
    protected:
 
        string model; //Модель
        Producer prod; //Изготовитель
    
    public:
        
    //virtual void sortClockByTradeMark() = 0; //Виртуальная функция сортировки информации о часах по названию марки (pure virtual function)
    //virtual void writeSortedDataIntoFile() = 0; //Виртуальная функция записи отсортированной информации в файл (pure virtual function)
};
 
class Mechanical: public Clock { //Класс-наследник (механические часы)
 
    private:
    
        int lifetime; //Продолжительность работы
        int w_period; //Гарантийный срок
    
    public:
 
        string getMechanicalClockModel() const; //Геттер (модель)
        Producer getMechanicalClockProducer(string, string) const; //Геттер (изготовитель)
        int getMechanicalClockLifeTime() const; //Геттер (продолжительность работы)
        int getMechanicalClockWarrantyPeriod() const; //Геттер (гарантийный срок)
        
        friend ifstream& operator>>(ifstream &in, Mechanical &obj) { 
        in >> obj.model
           >> obj.prod.t_mark
           >> obj.prod.c_origin
           >> obj.lifetime
           >> obj.w_period;
        return in;
    }
};
 
class Electronic: public Clock { //Класс-наследник (электронные часы)
 
    private:
    
        string battery_t; //Тип батареи
        string display_t; //Тип дисплея
    
    public:
        
        string getElectronicClockModel() const; //Геттер (модель)
        Producer getElectronicClockProducer(string, string) const; //Геттер (изготовитель)
        string getElectronicClockBatteryType() const; //Геттер (тип батареи)
        string getElectronicClockDisplayType() const; //Геттер (тип экрана)
        
        friend ifstream& operator>>(ifstream &in, Electronic &obj) { 
        in >> obj.model
           >> obj.prod.t_mark
           >> obj.prod.c_origin
           >> obj.battery_t
           >> obj.display_t;
        return in;
    }
};
   
int main() { 
    ifstream in("clock.txt");
    in.close();
    system("pause");
    return 0;
}
 
//Геттеры (механические часы):
 
string Mechanical::getMechanicalClockModel() const { //Модель (механические часы) 
    return model;
}
 
Producer Mechanical::getMechanicalClockProducer(string trademark, string country) const { //Изготовитель (механические часы) 
    Producer p;
    p.t_mark = trademark;
    p.c_origin = country;
    return p;
}
 
int Mechanical::getMechanicalClockLifeTime() const { //Продолжительность работы (механические часы) 
    return lifetime;
}
 
int Mechanical::getMechanicalClockWarrantyPeriod() const { //Гарантийный срок (механические часы)
    return w_period;
}
 
//Геттеры (электронные часы):
 
string Electronic::getElectronicClockModel() const { //Модель (электронные часы) 
    return model;
}
 
Producer Electronic::getElectronicClockProducer(string trademark, string country) const { //Изготовитель (электронные часы) 
    Producer p;
    p.t_mark = trademark;
    p.c_origin = country;
    return p;
}
 
string Electronic::getElectronicClockBatteryType() const { //Тип батареи (электронные часы) 
    return battery_t;
}
 
string Electronic::getElectronicClockDisplayType() const { //Тип экрана (электронные часы)
    return display_t;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.03.2019, 12:05
Ответы с готовыми решениями:

Работа с абстрактным классом
Доброго времени суток! Имеется небольшой класс: #include &lt;irrlicht.h&gt; class EngineInit { public: IrrlichtDevice* device...

Непонятки с абстрактным классом
У нуба возник вопрос :) Вот объявляю я абстрактный Inline класс. Ну под инлайн я имею ввиду, что он без cpp, реализация в H. #pragma...

Полиморфизм с абстрактным классом
Добрий день, нуждаюсь в помощи. У меня есть абстрактный класс IStudent_Manip и производный класс Student_Manipulator. Хочу сделать...

41
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 14:24  [ТС]
Студворк — интернет-сервис помощи студентам
zayats80888, данные получилось разделить, но теперь перед выводом куча пустых строк, вместо информации из первого подкласса.

Добавлено через 4 минуты
zayats80888, это не сложно сделать, но я хотел чтобы программа различала данные, так как их потом еще обрабатывать для каждого подкласса нужно. Ваш вариант прошел, но куча пустых строк теперь перед выводом.

Добавлено через 3 минуты
zayats80888, выдает лишние пробелы перед выводом. Не знаете как это можно исправить?

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
    int check_type(ifstream& is) {
        string str;
        int val;
        streampos pos = is.tellg();
        if (is >> str >> str >> str >> val >> val) {
            is.seekg(pos);
            return 1;
        }
            else {
                is.clear();
                is.seekg(pos);
                return 0;
            }
        }
 
class Electronic: public Clock { //Класс-наследник (электронные часы)
 
    private:
    
        string battery_t; //Тип батареи
        string display_t; //Тип дисплея
    
    public:
        
        string getElectronicClockModel() const; //Геттер (модель)
        Producer getElectronicClockProducer(string, string) const; //Геттер (изготовитель)
        string getElectronicClockBatteryType() const; //Геттер (тип батареи)
        string getElectronicClockDisplayType() const; //Геттер (тип экрана)
            
        friend ifstream& operator>>(ifstream &in, Electronic &obj) { 
            if (check_type(in)) {
            in.ignore(numeric_limits<streamsize>::max(), '\n');
            return in;
        }
        in >> obj.model
           >> obj.prod.t_mark
           >> obj.prod.c_origin
           >> obj.battery_t
           >> obj.display_t;
           return in;
    }
    
        friend ostream& operator<<(ostream &out, const Electronic &obj) {
        out << obj.getElectronicClockModel() << " " 
            //<< obj.getElectronicClockProducer(obj.prod.t_mark, obj.prod.c_origin) << " "
            << obj.getElectronicClockBatteryType() << " "
            << obj.getElectronicClockDisplayType() << "\n";
        return out;
    } 
};
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 14:26
Fixer_84, там выше Azazel-San предложил отличный вариант, а что касается вывода, имеет смысл определить виртуальный метод, возвращающий строку, сформированную из данных класса, и уже выводить её(вместо дружественной функции)
1
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 14:54  [ТС]
zayats80888, я определил виртуальный метод и реализовал его для электронных часов, но при добавлении разделителя (" " или "\n") эти специальные символы в количестве 8 штук (число полей для первого класса), как и в случае с дружественной функцией (значит дело не в ней), выскакивают перед выводом. Как-то можно это исправить? Проблема почти решена.

Добавлено через 8 минут
zayats80888, при этом, если разделитель не указывать, данные просто сливаются (то есть, считаны правильно). Что-то не так при выводе.
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 15:43
Fixer_84, лучше бы вы использовали вариант Azazel-San, мой корявый, набросал на коленке, суть в том что он просто не считывает данные, но объект формируется(как пустой)

Добавлено через 3 минуты
C++
1
2
3
4
5
6
7
8
9
10
 friend ifstream& operator>>(ifstream &in, Electronic &obj) {
     if (check_type(in)) {
         return in.setf(ios_base::failbit);
     }
     return in >> obj.model
        >> obj.prod.t_mark
        >> obj.prod.c_origin
        >> obj.battery_t
        >> obj.display_t;
}
а игнорить строку можно в вызывающем модуле
0
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 16:24  [ТС]
zayats80888, я так пробовал. Писал, что не равно пустой строке при выводе. Для одного поля объекта (если возвращать его в виртуальном методе) это сработало, но когда я складывал через пробел более одного геттера, эта пустая строка появлялась снова. Если я вам покажу код, вы сможете помочь исправить?

Добавлено через 3 минуты
zayats80888, вот:

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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
Создать класс Изготовитель cо следующими полями: 
    - торговая марка;
    - страна происхождения.
Создать базовый класс Часы (модель, изготовитель) и дочерние классы: 
    - механические часы (продолжительность работы, гарантийный срок); 
    - электронные часы (тип батареи, тип экрана);
    - использовать класс Изготовитель как поле класса Часы. 
Функции:
    - cчитать из текстового файла данные о разных часах; 
    - используя механизм виртуальных функций, в новый файл записать информацию о часах, отсортированных по названию марки; 
    - подсчитать количество часов указанного изготовителя с заданным типом батареи;
    - вывести информацию о механических часах с самым большим гарантийным сроком.
 
Пример входных данных:
 
    C4698/4 Candino Switzerland 35 2
    KP-1434M-E Kappa Italy 15 1
    ES-8091-01 Earnshaw England 10 2
    SYG194B Superdry England 20 1
    W0991G7 Guess USA 5 2
    JZ1065-05E Citizen Japan 15 3
    SKW2726 Skagen Denmark 10 5
    P.2.1.5 Putnik Russia 15 1
    
    A-163WA-1 Casio Japan Alkaline FRP
    A-168WEC-3E Casio Japan Lithium Plastic 
    T5K335 Timex USA Alkaline Mineral 
    SN05 SmartWatch China Lithium Plastic 
    SS022663000 Suunto Finland Alkaline Plastic 
    47326 StormDigitron England Lithium Mineral  
*/
 
#include <iostream>
#include <string>
#include <algorithm>
#include <fstream>
 
    using namespace std;
       
class Producer { //Класс Изготовитель (этот класс используется внутри другого класса Часы (композиция объектов))
 
    public:
 
        string t_mark; //Торговая марка
        string c_origin; //Страна происхождения
};
 
class Clock { //Базовый, абстрактный класс Часы
 
    protected:
 
        string model; //Модель
        Producer prod; //Изготовитель
    
    public:
        
    //virtual void sortClockByTradeMark() = 0; //Виртуальная функция сортировки информации о часах по названию марки (pure virtual function)
    virtual string writeSortedDataIntoFile() = 0; //Виртуальная функция записи отсортированной информации в файл (pure virtual function)
};
 
class Mechanical: public Clock { //Класс-наследник (механические часы)
 
    private:
    
        int lifetime; //Продолжительность работы
        int w_period; //Гарантийный срок
    
    public:
 
        string getMechanicalClockModel() const; //Геттер (модель)
        Producer getMechanicalClockProducer(string, string) const; //Геттер (изготовитель)
        int getMechanicalClockLifeTime() const; //Геттер (продолжительность работы)
        int getMechanicalClockWarrantyPeriod() const; //Геттер (гарантийный срок)
        
        friend ifstream& operator>>(ifstream &in, Mechanical &obj) { 
        in >> obj.model
           >> obj.prod.t_mark
           >> obj.prod.c_origin
           >> obj.lifetime
           >> obj.w_period;
        return in;
        }
        
        friend ostream& operator<<(ostream &out, const Mechanical &obj) {
        out << obj.getMechanicalClockModel() << " " 
            //<< obj.getMechanicalClockProducer(obj.prod.t_mark, obj.prod.c_origin) << " "
            << obj.getMechanicalClockLifeTime() << " "
            << obj.getMechanicalClockWarrantyPeriod() << "\n";
        return out;
    } 
};
 
    int check_type(ifstream& is) {
        string str;
        int val;
        streampos pos = is.tellg();
        if (is >> str >> str >> str >> val >> val) {
            is.seekg(pos);
            return 1;
        }
            else {
                is.clear();
                is.seekg(pos);
                return 0;
            }
        }
 
class Electronic: public Clock { //Класс-наследник (электронные часы)
 
    private:
    
        string battery_t; //Тип батареи
        string display_t; //Тип дисплея
    
    public:
        
        string getElectronicClockModel() const; //Геттер (модель)
        Producer getElectronicClockProducer(string, string) const; //Геттер (изготовитель)
        string getElectronicClockBatteryType() const; //Геттер (тип батареи)
        string getElectronicClockDisplayType() const; //Геттер (тип экрана)
        
        string writeSortedDataIntoFile() { //Виртуальный метод для вывода информации на экран
            return getElectronicClockBatteryType() + " " + getElectronicClockDisplayType();
        }
            
        friend ifstream& operator>>(ifstream &in, Electronic &obj) { 
            if (check_type(in)) {
            in.ignore(numeric_limits<streamsize>::max(), '\n');
            return in;
        }
        in >> obj.model
           >> obj.prod.t_mark
           >> obj.prod.c_origin
           >> obj.battery_t
           >> obj.display_t;
           return in;
        }
        
        /*
        friend ostream& operator<<(ostream &out, const Electronic &obj) {
        out << obj.getElectronicClockModel() << " " 
            //<< obj.getElectronicClockProducer(obj.prod.t_mark, obj.prod.c_origin) << " "
            << obj.getElectronicClockBatteryType() << " "
            << obj.getElectronicClockDisplayType() << "\n";
        return out;
        } 
        */
};
   
int main() { 
    ifstream in("clock.txt");
    Electronic e;
    while (in >> e) {
        if (e.writeSortedDataIntoFile() != "") {
            cout << e.writeSortedDataIntoFile();
            cout << "\n";
        }
    }
    in.close();
    system("pause");
    return 0;
}
 
//Геттеры (механические часы):
 
string Mechanical::getMechanicalClockModel() const { //Модель (механические часы) 
    return model;
}
 
Producer Mechanical::getMechanicalClockProducer(string trademark, string country) const { //Изготовитель (механические часы) 
    Producer p;
    p.t_mark = trademark;
    p.c_origin = country;
    return p;
}
 
int Mechanical::getMechanicalClockLifeTime() const { //Продолжительность работы (механические часы) 
    return lifetime;
}
 
int Mechanical::getMechanicalClockWarrantyPeriod() const { //Гарантийный срок (механические часы)
    return w_period;
}
 
//Геттеры (электронные часы):
 
string Electronic::getElectronicClockModel() const { //Модель (электронные часы) 
    return model;
}
 
Producer Electronic::getElectronicClockProducer(string trademark, string country) const { //Изготовитель (электронные часы) 
    Producer p;
    p.t_mark = trademark;
    p.c_origin = country;
    return p;
}
 
string Electronic::getElectronicClockBatteryType() const { //Тип батареи (электронные часы) 
    return battery_t;
}
 
string Electronic::getElectronicClockDisplayType() const { //Тип экрана (электронные часы)
    return display_t;
}
Проблема в 123 строке. Если геттер 1, то все хорошо, если больше - опять пустые строки...

Добавлено через 15 минут
zayats80888, понимаете, проблема в том, что я не хочу создавать дополнительный контейнер для хранения этой информации. Мне нужно, чтобы она хранилась в объектах этих двух подклассов при считывании. Дружественная функция получает доступ к приватным (не public или protected) полям, а данные в таком случае легко обрабатывать для каждого подкласса через соответствующие геттеры.
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 16:33
Цитата Сообщение от Fixer_84 Посмотреть сообщение
Если я вам покажу код
сейчас гляну
0
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 16:34  [ТС]
zayats80888, спасибо. Просто очень не хочется переделывать программу. Уже много сил брошено на написание кода.
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 17:07
Подправил:
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
Создать класс Изготовитель cо следующими полями:
    - торговая марка;
    - страна происхождения.
Создать базовый класс Часы (модель, изготовитель) и дочерние классы:
    - механические часы (продолжительность работы, гарантийный срок);
    - электронные часы (тип батареи, тип экрана);
    - использовать класс Изготовитель как поле класса Часы.
Функции:
    - cчитать из текстового файла данные о разных часах;
    - используя механизм виртуальных функций, в новый файл записать информацию о часах, отсортированных по названию марки;
    - подсчитать количество часов указанного изготовителя с заданным типом батареи;
    - вывести информацию о механических часах с самым большим гарантийным сроком.
 
Пример входных данных:
 
    C4698/4 Candino Switzerland 35 2
    KP-1434M-E Kappa Italy 15 1
    ES-8091-01 Earnshaw England 10 2
    SYG194B Superdry England 20 1
    W0991G7 Guess USA 5 2
    JZ1065-05E Citizen Japan 15 3
    SKW2726 Skagen Denmark 10 5
    P.2.1.5 Putnik Russia 15 1
 
    A-163WA-1 Casio Japan Alkaline FRP
    A-168WEC-3E Casio Japan Lithium Plastic
    T5K335 Timex USA Alkaline Mineral
    SN05 SmartWatch China Lithium Plastic
    SS022663000 Suunto Finland Alkaline Plastic
    47326 StormDigitron England Lithium Mineral
*/
 
#include <iostream>
#include <string>
#include <algorithm>
#include <fstream>
 
using namespace std;
 
class Producer { //Класс Изготовитель (этот класс используется внутри другого класса Часы (композиция объектов))
 
public:
 
    string t_mark; //Торговая марка
    string c_origin; //Страна происхождения
};
 
class Clock { //Базовый, абстрактный класс Часы
 
protected:
 
    string model; //Модель
    Producer prod; //Изготовитель
 
public:
 
    //virtual void sortClockByTradeMark() = 0; //Виртуальная функция сортировки информации о часах по названию марки (pure virtual function)
    virtual string writeSortedDataIntoFile() = 0; //Виртуальная функция записи отсортированной информации в файл (pure virtual function)
};
 
class Mechanical : public Clock { //Класс-наследник (механические часы)
 
private:
 
    int lifetime; //Продолжительность работы
    int w_period; //Гарантийный срок
 
public:
 
    string getMechanicalClockModel() const; //Геттер (модель)
    Producer getMechanicalClockProducer(string, string) const; //Геттер (изготовитель)
    int getMechanicalClockLifeTime() const; //Геттер (продолжительность работы)
    int getMechanicalClockWarrantyPeriod() const; //Геттер (гарантийный срок)
 
    friend ifstream& operator>>(ifstream &in, Mechanical &obj) {
        in >> obj.model
            >> obj.prod.t_mark
            >> obj.prod.c_origin
            >> obj.lifetime
            >> obj.w_period;
        return in;
    }
 
    friend ostream& operator<<(ostream &out, const Mechanical &obj) {
        out << obj.getMechanicalClockModel() << " "
            //<< obj.getMechanicalClockProducer(obj.prod.t_mark, obj.prod.c_origin) << " "
            << obj.getMechanicalClockLifeTime() << " "
            << obj.getMechanicalClockWarrantyPeriod() << "\n";
        return out;
    }
};
 
int check_type(ifstream& is) {
    string str;
    int val;
    streampos pos = is.tellg();
    is >> str >> str >> str >> val >> val;
    if (!is.fail()) {
        is.seekg(pos);
        return 1;
    }
    else {
        is.seekg(pos);
        return 0;
    }
}
 
class Electronic : public Clock { //Класс-наследник (электронные часы)
 
private:
 
    string battery_t; //Тип батареи
    string display_t; //Тип дисплея
 
public:
 
    string getElectronicClockModel() const; //Геттер (модель)
    Producer getElectronicClockProducer(string, string) const; //Геттер (изготовитель)
    string getElectronicClockBatteryType() const; //Геттер (тип батареи)
    string getElectronicClockDisplayType() const; //Геттер (тип экрана)
 
    string writeSortedDataIntoFile() { //Виртуальный метод для вывода информации на экран
        return getElectronicClockBatteryType() + " " + getElectronicClockDisplayType();
    }
 
    friend ifstream& operator>>(ifstream &in, Electronic &obj) {
        if (check_type(in) == 0) return in;
        
        in >> obj.model
            >> obj.prod.t_mark
            >> obj.prod.c_origin
            >> obj.battery_t
            >> obj.display_t;
        return in;
    }
 
    /*
    friend ostream& operator<<(ostream &out, const Electronic &obj) {
    out << obj.getElectronicClockModel() << " "
        //<< obj.getElectronicClockProducer(obj.prod.t_mark, obj.prod.c_origin) << " "
        << obj.getElectronicClockBatteryType() << " "
        << obj.getElectronicClockDisplayType() << "\n";
    return out;
    }
    */
};
 
int main() {
    ifstream in("clock.txt");
    if (!in) return 1;
    Electronic e;
    while (in.peek()!=EOF) {
        in >> e;
        if (in.fail()) {
            in.clear();
            in.ignore(numeric_limits<streamsize>::max(), '\n');
        }
        else {          
            cout << e.writeSortedDataIntoFile();
            cout << "\n";
        }
    }
    in.close();
    system("pause");
    return 0;
}
 
//Геттеры (механические часы):
 
string Mechanical::getMechanicalClockModel() const { //Модель (механические часы) 
    return model;
}
 
Producer Mechanical::getMechanicalClockProducer(string trademark, string country) const { //Изготовитель (механические часы) 
    Producer p;
    p.t_mark = trademark;
    p.c_origin = country;
    return p;
}
 
int Mechanical::getMechanicalClockLifeTime() const { //Продолжительность работы (механические часы) 
    return lifetime;
}
 
int Mechanical::getMechanicalClockWarrantyPeriod() const { //Гарантийный срок (механические часы)
    return w_period;
}
 
//Геттеры (электронные часы):
 
string Electronic::getElectronicClockModel() const { //Модель (электронные часы) 
    return model;
}
 
Producer Electronic::getElectronicClockProducer(string trademark, string country) const { //Изготовитель (электронные часы) 
    Producer p;
    p.t_mark = trademark;
    p.c_origin = country;
    return p;
}
 
string Electronic::getElectronicClockBatteryType() const { //Тип батареи (электронные часы) 
    return battery_t;
}
 
string Electronic::getElectronicClockDisplayType() const { //Тип экрана (электронные часы)
    return display_t;
}
1
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 18:11  [ТС]
zayats80888, теперь выводит совсем не то что нужно Спасибо, что попытались исправить.
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 18:26
Цитата Сообщение от Fixer_84 Посмотреть сообщение
теперь выводит совсем не то что нужно
А что нужно? То что описано в функции writeSortedDataIntoFile() то и выводит.

Добавлено через 1 минуту
Правда при вашем подходе я не совсем понимаю зачем нужен абстрактный класс и виртуальные методы, вы же все равно обращаетесь к объекту конкретного класса

Добавлено через 2 минуты
Вот если бы у вас была внешняя функция void WriteSortedData(const Clock& obj) то да
0
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 18:29  [ТС]
zayats80888, он для файла clock.txt:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
C4698/4 Candino Switzerland 35 2
KP-1434M-E Kappa Italy 15 1
ES-8091-01 Earnshaw England 10 2
SYG194B Superdry England 20 1
W0991G7 Guess USA 5 2
JZ1065-05E Citizen Japan 15 3
SKW2726 Skagen Denmark 10 5
P.2.1.5 Putnik Russia 15 1   
A-163WA-1 Casio Japan Alkaline FRP
A-168WEC-3E Casio Japan Lithium Plastic 
T5K335 Timex USA Alkaline Mineral 
SN05 SmartWatch China Lithium Plastic 
SS022663000 Suunto Finland Alkaline Plastic 
47326 StormDigitron England Lithium Mineral

Должен вывести:


C++
1
2
3
4
5
6
Alkaline FRP
Lithium Plastic
Alkaline Mineral
Lithium Plastic
Alkaline Plastic
Lithium Mineral
Этого, к сожалению, не происходит. У вас выводит? У меня нет. Хотя предыдущая версия вашего кода работает, но выводит с пустыми строками.

Добавлено через 1 минуту
Вот описание виртуального метода:

C++
1
2
3
string writeSortedDataIntoFile() { //Виртуальный метод для вывода информации на экран
    return getElectronicClockBatteryType() + " " + getElectronicClockDisplayType();
}
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 18:31
А вообще, если нужно сортировать, то нужен контейнер (vector<Clock*> например)

Добавлено через 1 минуту
Fixer_84, пардон, я не то считывал
1
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 18:49  [ТС]
zayats80888, буду вам очень благодарен если получится исправить. Общая сортировка будет нужна, вы правы. Но для пунктов с обработкой информации (из задания) для каждого подкласса, это считывание было бы гораздо удобней. Вообщем, если не получится буду переделывать все с дополнительным контейнером, но ведь по нему тоже пробегать придется геттерами, а они должны работать для каждого подкласса правильно.
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 19:22
исправил
Кликните здесь для просмотра всего текста
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
Создать класс Изготовитель cо следующими полями:
    - торговая марка;
    - страна происхождения.
Создать базовый класс Часы (модель, изготовитель) и дочерние классы:
    - механические часы (продолжительность работы, гарантийный срок);
    - электронные часы (тип батареи, тип экрана);
    - использовать класс Изготовитель как поле класса Часы.
Функции:
    - cчитать из текстового файла данные о разных часах;
    - используя механизм виртуальных функций, в новый файл записать информацию о часах, отсортированных по названию марки;
    - подсчитать количество часов указанного изготовителя с заданным типом батареи;
    - вывести информацию о механических часах с самым большим гарантийным сроком.
 
Пример входных данных:
 
    C4698/4 Candino Switzerland 35 2
    KP-1434M-E Kappa Italy 15 1
    ES-8091-01 Earnshaw England 10 2
    SYG194B Superdry England 20 1
    W0991G7 Guess USA 5 2
    JZ1065-05E Citizen Japan 15 3
    SKW2726 Skagen Denmark 10 5
    P.2.1.5 Putnik Russia 15 1
 
    A-163WA-1 Casio Japan Alkaline FRP
    A-168WEC-3E Casio Japan Lithium Plastic
    T5K335 Timex USA Alkaline Mineral
    SN05 SmartWatch China Lithium Plastic
    SS022663000 Suunto Finland Alkaline Plastic
    47326 StormDigitron England Lithium Mineral
*/
 
#include <iostream>
#include <string>
#include <algorithm>
#include <fstream>
 
using namespace std;
 
class Producer { //Класс Изготовитель (этот класс используется внутри другого класса Часы (композиция объектов))
 
public:
 
    string t_mark; //Торговая марка
    string c_origin; //Страна происхождения
};
 
class Clock { //Базовый, абстрактный класс Часы
 
protected:
 
    string model; //Модель
    Producer prod; //Изготовитель
 
public:
 
    //virtual void sortClockByTradeMark() = 0; //Виртуальная функция сортировки информации о часах по названию марки (pure virtual function)
    virtual string writeSortedDataIntoFile() = 0; //Виртуальная функция записи отсортированной информации в файл (pure virtual function)
};
 
class Mechanical : public Clock { //Класс-наследник (механические часы)
 
private:
 
    int lifetime; //Продолжительность работы
    int w_period; //Гарантийный срок
 
public:
 
    string getMechanicalClockModel() const; //Геттер (модель)
    Producer getMechanicalClockProducer(string, string) const; //Геттер (изготовитель)
    int getMechanicalClockLifeTime() const; //Геттер (продолжительность работы)
    int getMechanicalClockWarrantyPeriod() const; //Геттер (гарантийный срок)
 
    friend ifstream& operator>>(ifstream &in, Mechanical &obj) {
        in >> obj.model
            >> obj.prod.t_mark
            >> obj.prod.c_origin
            >> obj.lifetime
            >> obj.w_period;
        return in;
    }
 
    friend ostream& operator<<(ostream &out, const Mechanical &obj) {
        out << obj.getMechanicalClockModel() << " "
            //<< obj.getMechanicalClockProducer(obj.prod.t_mark, obj.prod.c_origin) << " "
            << obj.getMechanicalClockLifeTime() << " "
            << obj.getMechanicalClockWarrantyPeriod() << "\n";
        return out;
    }
};
 
int check_type(ifstream& is) {
    string str;
    int val;
    streampos pos = is.tellg();
    is >> str >> str >> str >> val >> val;
    if (!is.fail()) {
        is.seekg(pos);
        return 1;
    }
    else {
        is.clear();
        is.seekg(pos);
        return 0;
    }
}
 
class Electronic : public Clock { //Класс-наследник (электронные часы)
 
private:
 
    string battery_t; //Тип батареи
    string display_t; //Тип дисплея
 
public:
 
    string getElectronicClockModel() const; //Геттер (модель)
    Producer getElectronicClockProducer(string, string) const; //Геттер (изготовитель)
    string getElectronicClockBatteryType() const; //Геттер (тип батареи)
    string getElectronicClockDisplayType() const; //Геттер (тип экрана)
 
    string writeSortedDataIntoFile() { //Виртуальный метод для вывода информации на экран
        return getElectronicClockBatteryType() + " " + getElectronicClockDisplayType();
    }
 
    friend ifstream& operator>>(ifstream &in, Electronic &obj) {
        if (check_type(in) == 1) {
            in.setstate(ios_base::failbit);
            return in;
        }
        
        in >> obj.model
            >> obj.prod.t_mark
            >> obj.prod.c_origin
            >> obj.battery_t
            >> obj.display_t;
        return in;
    }
 
    /*
    friend ostream& operator<<(ostream &out, const Electronic &obj) {
    out << obj.getElectronicClockModel() << " "
        //<< obj.getElectronicClockProducer(obj.prod.t_mark, obj.prod.c_origin) << " "
        << obj.getElectronicClockBatteryType() << " "
        << obj.getElectronicClockDisplayType() << "\n";
    return out;
    }
    */
};
 
int main() {
    ifstream in("clock.txt");
    if (!in) return 1;
    Electronic e;
    while (in.peek()!=EOF) {
        in >> e;
        if (in.fail()) {
            in.clear();
            in.ignore(numeric_limits<streamsize>::max(), '\n');
        }
        else {          
            cout << e.writeSortedDataIntoFile();
            cout << "\n";
        }
    }
    in.close();
    system("pause");
    return 0;
}
 
//Геттеры (механические часы):
 
string Mechanical::getMechanicalClockModel() const { //Модель (механические часы) 
    return model;
}
 
Producer Mechanical::getMechanicalClockProducer(string trademark, string country) const { //Изготовитель (механические часы) 
    Producer p;
    p.t_mark = trademark;
    p.c_origin = country;
    return p;
}
 
int Mechanical::getMechanicalClockLifeTime() const { //Продолжительность работы (механические часы) 
    return lifetime;
}
 
int Mechanical::getMechanicalClockWarrantyPeriod() const { //Гарантийный срок (механические часы)
    return w_period;
}
 
//Геттеры (электронные часы):
 
string Electronic::getElectronicClockModel() const { //Модель (электронные часы) 
    return model;
}
 
Producer Electronic::getElectronicClockProducer(string trademark, string country) const { //Изготовитель (электронные часы) 
    Producer p;
    p.t_mark = trademark;
    p.c_origin = country;
    return p;
}
 
string Electronic::getElectronicClockBatteryType() const { //Тип батареи (электронные часы) 
    return battery_t;
}
 
string Electronic::getElectronicClockDisplayType() const { //Тип экрана (электронные часы)
    return display_t;
}


Добавлено через 27 минут
Вот простенький контейнер(только в базовом классе добавьте virtual ~Clock() {}):
C++
1
2
3
4
5
6
7
8
9
10
11
12
class clock_vector {
    vector<Clock*> cv;
public:
    void push_back(Clock* c) { cv.push_back(c); }
 
    ~clock_vector() { for (auto i : cv) delete i; }
 
    typedef vector<Clock*>::iterator iterator;
 
    iterator begin() { return cv.begin(); }
    iterator end() { return cv.end(); }
};
использовать его можно так:
C++
1
2
3
4
clock_vector v;
Electronic e;
//читаем из файла
v.push_back(new Electronic(e));
1
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 20:24  [ТС]
zayats80888, спасибо вам большое! Теперь буду доделывать программу. Извините, что отнял у вас время. Просто не знал как это сделать для отдельных подклассов через дружественные функции. Да и с классами мало работал.

Добавлено через 31 минуту
zayats80888, проблема возникает, если данные перемешаны. У вас программа правильно выводит? Вот пример данных:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
A-168WEC-3E Casio Japan Lithium Plastic 
T5K335 Timex USA Alkaline Mineral
C4698/4 Candino Switzerland 35 2
KP-1434M-E Kappa Italy 15 1
W0991G7 Guess USA 5 2
JZ1065-05E Citizen Japan 15 3
SKW2726 Skagen Denmark 10 5
P.2.1.5 Putnik Russia 15 1
A-163WA-1 Casio Japan Alkaline FRP 
SN05 SmartWatch China Lithium Plastic 
SS022663000 Suunto Finland Alkaline Plastic
ES-8091-01 Earnshaw England 10 2
SYG194B Superdry England 20 1
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 20:32
Fixer_84, да нормально, считал 5 объектов
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 20:34
0
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 20:47  [ТС]
zayats80888, а у меня код выше считал так:

C++
1
2
3
4
5
6
Plastic T5K335
Candino Switzerland
15 1
Alkaline FRP
Lithium Plastic
Alkaline Plastic
0
 Аватар для zayats80888
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
21.03.2019, 20:53
Цитата Сообщение от Fixer_84 Посмотреть сообщение
а у меня код выше считал так
Возможно ошибка в самом файле, проверьте лишний символ или пробел

Добавлено через 1 минуту
ну или используя выше предложенный вектор, посмотрите какая именно строка считывается с ошибкой
0
 Аватар для Fixer_84
1505 / 969 / 812
Регистрация: 30.04.2016
Сообщений: 3,337
21.03.2019, 21:09  [ТС]
zayats80888, если данные идут друг за другом, то считывает нормально, а если вперемешку выводит какую-то белиберду. Вообщем буду пробовать дальше. Спасибо большое за помощь!

Добавлено через 2 минуты
zayats80888, просто весь смысл виртуального метода в том, что он сам понимает для какого класса и когда себя вызывать. Поэтому я и хотел разделить данные так. Но я рад, что у вас все работает. Буду искать проблему на своей стороне.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.03.2019, 21:09

Создать иерархию наследования с абстрактным базовым классом
Доброго времени суток! Помогите, пожалуйста, сделать: 2) Создать абстрактный базовый класс с виртуальной функцией &quot;Площадь&quot;....

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

Теория по абстрактным типам данных
В общем нужно сделать лабораторную работу по абстрактным типам данных на Си. Не могу найти подходящую теорию, подкиньте пожалуйста где есть...

Задача с абстрактным типом данных
Даны сведения о 14 кубиках: длина ребра в сантиметрах, его цвет и материал (деревянный, металлический, пластмассовый). Найти количество...

работа с классом
пишу класс быстрой математики (знаю что многие делали в инете дофига всего, но всё же) сделал таблицу корней в общем то всё работает...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Транслитерация текста с кириллицы на латиницу (вариант №2)
Maks 13.11.2026
Обновленная версия ранее созданной обработки. Добавлено: - Проверка исходного текста на кириллицу, через обращение к стандартной функции "ТолькоКириллицаВСтроке" из общего модуля. . .
Часы с термометром и праздничным календарем
yariko 12.11.2026
Сегодня мы рассмотрим как можно сделать отличные многофункциональные часы. Итак, поставим конкретную задачу: разработать часы с календарем, двумя термодатчиками, выводом поздравительных сообщений. . .
Транслитерация текста с кириллицы на латиницу (вариант №1)
Maks 11.11.2026
Решил облегчить жизнь себе и коллегам админам при создании электронных почтовых ящиков для пользователей, в результате написал обработку "Транслитерация текста" с кириллицы на латиницу, а в ней. . .
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru