Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.81
art3330
10 / 10 / 1
Регистрация: 16.12.2012
Сообщений: 141
#1

Перегрузка операций ввода/вывода - C++

06.04.2013, 10:54. Просмотров 2069. Ответов 61
Метки нет (Все метки)

Доброго времени суток господа и дамы! Нужно решить один нюанс. Никак не получается.
Есть код:
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
#include <iostream>
#include <stdlib.h>
 
using namespace std;
 
class shape {
    
    protected:  
        int x,y;
        shape(int q, int w):x(q),y(w)   {}; 
        shape():x(0),y(0)   {} ;
        
    public: 
        virtual void read()=0;
        virtual void write()=0;
        
};
 
class point: public shape {
            
    public:
        virtual void read() {
            cout<<"enter x,y \n";
            cin>>x>>y;
            system("clear");
        }
        
        virtual void write() {cout<<"point: \n"<<x<<y<<endl;}
        
};
 
class rectangle: public point {
    
    private:
        int x2,y2;
        
    public:
        rectangle(int r, int e):x2(r),y2(e) {};
        rectangle():x2(0),y2(0) {};
        
        virtual void read() {
            cout<<"enter x1,y1,x2,y2 \n";
            cin>>x>>y>>x2>>y2;
            system("clear");
        }
        
        virtual void write() {cout<<"rectangle: \n"<<x<<y<<x2<<y2<<endl;}
};
 
class circle: public rectangle {
    private:
        int r;
        
    public:
        
        circle(int c ):r(c) {};
        circle():r(0) {};
        
        virtual void read() {
            cout<<"enter x1,y1,r \n";
            cin>>x>>y>>r;
            system("clear");
        }
        
        virtual void write() {cout<<"circle: \n"<<x<<y<<r<<endl;}
};
 
int main() {
    int n;
    cout<<"Enter the dimension of the array: ";
    cin>>n;
    system("clear");
    shape *array[n];
    shape *pointer;
    for(int i=1;i<=n;i++){
        int number;
        do{
            cout<<"# "<<i<<"/"<<n<<"\n";
            cout<<"Select a shape \n"
            <<"1.Point\n"
            <<"2.Rectangle\n"
            <<"3.Circle\n";
            cin>>number;
            system("clear");
        }
        while(number>3 || number<1);
        switch (number){
            case 1: 
                pointer=new point; pointer->read () ;break;
            case 2: 
                pointer=new rectangle; pointer->read () ;break;
            case 3: 
                pointer=new circle;  pointer->read ();break;
        }
        array[i]=pointer;
    }
    for(int i=1;i<=n;i++) {array[i]->write();}
    return 0;
}
Все красиво работает, но преподаватель попросил сделать ввод и вывод с помощью перегруженных операторов, собственно, ввода и вывода. Искал я информацию в интернете. Ничего толкового не нашел. Можете помочь с перегрузкой операторов ввода. А особенно с операторами вывода. Чтобы не пришлось кардинально менять main.
Заранее спасибо.
p.s. смотрел я подобные вопросы на форуме. Там немного не то, что надо.
p.p.s. если знаете хороший материал по перегрузкам операторов, то поделитесь пожалуйста.

Добавлено через 11 часов 28 минут
Имеется ввиду перегрузка << и >>, будут они вместо моих методов.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5415 / 4811 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.04.2013, 11:13     Перегрузка операций ввода/вывода #2
C++
1
2
friend istream& operator>>(istream& in, A& object);
friend ostream& operator<<(ostream& out, const A& object);
В реализациях делаете то же, что и в своих методах (read(), write()), заменяя cin на in, cout на out, возвращаете in, out.
art3330
10 / 10 / 1
Регистрация: 16.12.2012
Сообщений: 141
06.04.2013, 11:16  [ТС]     Перегрузка операций ввода/вывода #3
Благодарю. Попытаюсь сделать =)
alsav22
5415 / 4811 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.04.2013, 12:23     Перегрузка операций ввода/вывода #4
C++
1
shape *array[n];
Здесь ошибка. Размер массива (не динамического) должен быть константой.

Добавлено через 1 час 2 минуты
Будут проблемы с виртуальным базовым классом. Функции дружественные, их виртуальными не сделать. Придётся менять main(). Если перегрузить их как методы класса, тогда можно сохранить виртуальность и всё, что с ней связано, но синтаксис применения этих операторов будет необычный (понравится ли это преподавателю?).

Добавлено через 1 минуту
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <stdlib.h>
 
using namespace std;
 
class shape {
    
    protected:  
        int x,y;
        shape(int q, int w):x(q),y(w)   {}; 
        shape():x(0),y(0)   {} ;
        
    public: 
        virtual istream& operator>>(istream& in) = 0;
        virtual ostream& operator<<(ostream& out) = 0;
        
};
 
class point: public shape {
            
    public:
        istream& operator>>(istream& in)
        {
            cout << "enter x,y \n";
            in >> x >> y;
            system("clear");
            return in;
        }
        
        ostream& operator<<(ostream& out)
        {
            cout << "point: \n"<< x << y << endl;
            return out;
        }
        
};
 
class rectangle: public point {
    
    private:
        int x2,y2;
        
    public:
        rectangle(int r, int e):x2(r),y2(e) {};
        rectangle():x2(0),y2(0) {};
        
        virtual istream& operator>>(istream& in)
        {
            cout<<"enter x1,y1,x2,y2 \n";
            in >> x >> y >> x2 >> y2;
            system("clear");
            return in;
        }
        
        virtual ostream& operator<<(ostream& out)
        {
            cout<<"rectangle: \n"<< x << y << x2 << y2 << endl;
            return out;
        }
};
 
class circle: public rectangle {
    private:
        int r;
        
    public:
        
        circle(int c ):r(c) {};
        circle():r(0) {};
        
        virtual istream& operator>>(istream& in)
        {
            cout<<"enter x1,y1,r \n";
            in >> x >> y >> r;
            system("clear");
            return in;
        }
        
        virtual ostream& operator<<(ostream& out)
        {
            cout<<"circle: \n" << x << y << r << endl;
            return out;
        }
};
 
int main() 
{
    const int n = 3;
    cout<<"Enter the dimension of the array: ";
    
    system("clear");
    shape *array[n];
    shape *pointer;
    
    for(int i=1;i<=n;i++){
        int number;
        do{
            cout<<"# "<<i<<"/"<<n<<"\n";
            cout<<"Select a shape \n"
            <<"1.Point\n"
            <<"2.Rectangle\n"
            <<"3.Circle\n";
            cin>>number;
            system("clear");
        }
        while(number > 3 || number < 1);
        switch (number){
            case 1: 
                pointer=new point; *pointer >> cin; break;
            case 2: 
                pointer=new rectangle; *pointer >> cin;break;
            case 3: 
                pointer=new circle;  *pointer >> cin;break;
        }
        array[i]=pointer;
    }
    for(int i=1;i<=n;i++) {*(array[i]) << cout;}
    return 0;
}
pi_X_el
Заблокирован
06.04.2013, 14:16     Перегрузка операций ввода/вывода #5
Цитата Сообщение от alsav22 Посмотреть сообщение
Размер массива (не динамического) должен быть константой.
В CodeBlocks почему то можно не делать константой. Все равно скомпилируется. Не знаете почему так?

Добавлено через 1 минуту
А в Visual Studio уже так не сделаешь. Требует константу
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
06.04.2013, 14:43     Перегрузка операций ввода/вывода #6
Цитата Сообщение от pi_X_el Посмотреть сообщение
В CodeBlocks почему то можно не делать константой. Все равно скомпилируется. Не знаете почему так?
В нем препроцессор от GCC
alsav22
5415 / 4811 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.04.2013, 16:04     Перегрузка операций ввода/вывода #7
Цитата Сообщение от pi_X_el Посмотреть сообщение
В CodeBlocks почему то можно не делать константой. Все равно скомпилируется. Не знаете почему так?
Особенности компилятора, но правильно - константой.
art3330
10 / 10 / 1
Регистрация: 16.12.2012
Сообщений: 141
06.04.2013, 16:05  [ТС]     Перегрузка операций ввода/вывода #8
Цитата Сообщение от alsav22 Посмотреть сообщение
while(number > 3 || number < 1);
switch (number){
case 1:
pointer=new point; *pointer >> cin; break;
case 2:
pointer=new rectangle; *pointer >> cin;break;
case 3:
pointer=new circle; *pointer >> cin;break;
}
array[i]=pointer;
}
for(int i=1;i<=n;i++) {*(array[i]) << cout;}
return 0;
}
А почему у нас так получается, что эти операторы стоят не слева, а справа?
pi_X_el
Заблокирован
06.04.2013, 16:21     Перегрузка операций ввода/вывода #9
Цитата Сообщение от programina Посмотреть сообщение
В нем препроцессор от GCC
и...
Не могли бы поподробней объяснить?!
art3330
10 / 10 / 1
Регистрация: 16.12.2012
Сообщений: 141
06.04.2013, 16:22  [ТС]     Перегрузка операций ввода/вывода #10
alsav22, сделал как Вы написали, все работает, но немного не понимаю сути. То есть как работает.
alsav22
5415 / 4811 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.04.2013, 16:25     Перегрузка операций ввода/вывода #11
Цитата Сообщение от art3330 Посмотреть сообщение
А почему у нас так получается, что эти операторы стоят не слева, а справа?
!!!
Цитата Сообщение от alsav22 Посмотреть сообщение
Если перегрузить их как методы класса, тогда можно сохранить виртуальность и всё, что с ней связано, но синтаксис применения этих операторов будет необычный
Добавлено через 57 секунд
Цитата Сообщение от art3330 Посмотреть сообщение
но немного не понимаю сути. То есть как работает.
Что конкретно непонятно?
art3330
10 / 10 / 1
Регистрация: 16.12.2012
Сообщений: 141
06.04.2013, 16:27  [ТС]     Перегрузка операций ввода/вывода #12
А по поводу того, что надо, чтобы n была константой, сделал так
C++
1
2
3
4
int k;
cout<<"Enter the dimension of the array: ";
cin>>k;
const int n=k;
Добавлено через 1 минуту
Цитата Сообщение от alsav22 Посмотреть сообщение
но синтаксис применения этих операторов будет необычный
Я понимаю, что необычный, мне просто интересно почему именно так.
Цитата Сообщение от alsav22 Посмотреть сообщение
Что конкретно непонятно?
Непонятно то, что я чуть выше написал. Про необычный синтаксис =)
pi_X_el
Заблокирован
06.04.2013, 16:29     Перегрузка операций ввода/вывода #13
размер массива в VC должен быть констанстой!

Добавлено через 53 секунды
const int a[10];

Добавлено через 36 секунд
10 уже никак не изменишь. Я прав? Ведь 10 - это константа!
art3330
10 / 10 / 1
Регистрация: 16.12.2012
Сообщений: 141
06.04.2013, 16:32  [ТС]     Перегрузка операций ввода/вывода #14
Цитата Сообщение от pi_X_el Посмотреть сообщение
размер массива в VC должен быть констанстой!
Добавлено через 53 секунды
const int a[10];
Если я делаю как написано у вас, то вот в этой строке выдается ошибка
C++
1
for(int i=1;i<=n;i++) {*(array[i])<<cout;}
passing «const Shape» as «this» argument of «virtual std::ostream& Shape::operator<<(std::ostream&)» discards qualifiers [-fpermissive]

Добавлено через 37 секунд
pi_X_el, Ну так у меня n это константа, которую мы никак не можем изменить. Разве нет ?
alsav22
5415 / 4811 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.04.2013, 16:33     Перегрузка операций ввода/вывода #15
Если операторы - это методы класса, то первым должен стоять объект класса, который и вызывает этот метод. Т.е.,
*pointer. operator>>(cin);
pi_X_el
Заблокирован
06.04.2013, 16:33     Перегрузка операций ввода/вывода #16
Цитата Сообщение от art3330 Посмотреть сообщение
в этой строке выдается ошибка
Цитата Сообщение от art3330 Посмотреть сообщение
i<=n;
Выход за границы массива!
art3330
10 / 10 / 1
Регистрация: 16.12.2012
Сообщений: 141
06.04.2013, 16:35  [ТС]     Перегрузка операций ввода/вывода #17
alsav22, Точно-точно. Спасибо. Понял =)
А если перегрузку не делать виртуальной, то как будет?
Просто я тогда сделаю виртуальными какие-нибудь другие методы, а перегрузка пусть будет не виртуальной и не методами класса.
alsav22
5415 / 4811 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.04.2013, 16:36     Перегрузка операций ввода/вывода #18
Цитата Сообщение от art3330 Посмотреть сообщение
Если я делаю как написано у вас
Где у меня что написано? Размер массива должен быть константой, но не сам массив. Просто:
C++
1
int a[10];
Или:
C++
1
2
int n = 10;
int a[n];
art3330
10 / 10 / 1
Регистрация: 16.12.2012
Сообщений: 141
06.04.2013, 16:36  [ТС]     Перегрузка операций ввода/вывода #19
Мы операторы эти перегружаем вне классов, указывая в качестве параметров ссылку на объект какого - нибудь класса. Так?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.04.2013, 16:38     Перегрузка операций ввода/вывода
Еще ссылки по теме:

Перегрузка операторов ввода/вывода C++
C++ Перегрузка операций ввода/вывода в шаблоне класса
Перегрузка вывода и ввода C++
C++ Перегрузка операторов ввода\вывода
Перегрузка потока ввода-вывода C++

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

Или воспользуйтесь поиском по форуму:
alsav22
5415 / 4811 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.04.2013, 16:38     Перегрузка операций ввода/вывода #20
Цитата Сообщение от pi_X_el Посмотреть сообщение
Выход за границы массива!
Да, там выход. Эти ошибки я не проверял, только те, что компилятор показал.
Yandex
Объявления
06.04.2013, 16:38     Перегрузка операций ввода/вывода
Ответ Создать тему
Опции темы

Текущее время: 18:54. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru