Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.67
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
#1

Перегрузка операций '<<' и '>>' - C++

17.10.2010, 16:52. Просмотров 2059. Ответов 32
Метки нет (Все метки)

Добрый вечер всем
У меня вот такое задание:
Создайте класс, реализующий однонаправленную очередь. В интерфейс класса должны входить перегруженные операции:
1) добавить элемент в конец очереди (<<);
2) извлечь элемент из начала очереди (>>).

Вот что смог написать (что не мог я закоментил):
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
#include <string.h>
#include <iostream>
using namespace std;
class Ocher{
private:
    struct Element{     // структура, задающая элемент списка
        int key;        // поле для хранения данных
        Element *next;  // указатель на следующий элемент
    };
    Element* pbeg;//начало очереди
    Element* pend;//конец очереди
public:
    Ocher(){
        Element* pbeg = 0;
        Element* pend = 0;
    }
    int operator <<(int a);
    int operator >>(Element** pbeg);
    void print(){
        while (pbeg != 0){
            Element *ph = pbeg;
            pbeg=pbeg->next;
            cout<<" "<<ph->key;
        }
    }
}
int Ocher::operator << (int a){
    Element* ph = new Element;
    ph->key = a;
    ph->next = 0;
    if (*pend!=0){   //здесь везде подчеркивает знак '=', почему незнаю
        (*pend)->next = ph;
        *pend = ph;
    }
    else{
        *pbeg = ph;
        *pend = ph;
    }
    return 0;
}
 
int Ocher::operator>>(Element** pbeg){
    int d = (*pbeg)->key;
    Element* ph = *pbeg;
    *pbeg = (*pbeg)->next;
    delete ph;
    return d;
}
 
int main(){
    setlocale(LC_ALL,"Russian");
    Ocher w;
    int b,a;
    while(true){
        system("cls");
        cout<<"1) Заполнить очередь"<<endl;
        cout<<"2) Вывести на экран"<<endl;
        cout<<"3) Удалить элемент"<<endl;
        cout<<"0) Выход"<<endl;
        cout<<"Ввод: "; cin>>b;
        if (b == 1){
            system("cls");
            cout<<"Введите значение: ";
            cin>>a;
            w<<a;
            cin.clear();
            fflush(stdin);
            continue;
        }
        if (b == 2){
            system("cls");
            cout<<"Список: ";
            w.print;//здесь ошибка (из за точки), хочу что бы распечаталсся список
            while (true){
                cout<<"\n0) Выход: ";
                int z; cin>>z;
                if (z == 0) break;
                cin.clear();
                fflush(stdin);
                continue;
            }
            cin.clear();
            fflush(stdin);
            continue;
        }
        if (b == 3){
            //Здесь не знаю как сделать что бы из очереди удалился первый элемент
        }
        system("cls");
        if (b == 0) break;
 
    }
 
    return 0;
}

http://www.cyberforum.ru/cpp-beginners/thread1186617.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.10.2010, 16:52
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Перегрузка операций '<<' и '>>' (C++):

Перегрузка операций
C++ ругается когда я пытаюсь сделать след-ю перегрузку операций. У меня...

Перегрузка операций!
Здравствуйте, у меня есть код (работы со строками) и нужно перегрузить...

Перегрузка операций
Здравствуйте, помогите реализовать программу: Класс - множество set....

Перегрузка операций
Уважаемые программисты! Помогите новичку! Мне нужно написать программу, в...

Перегрузка операций
Разработайте программу на языке С++, используя пользовательский тип данных –...

32
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 17:20 #2
Я думаю, смысл создавать подобный интерфейс для работы с очередью в том, чтобы можно было "сцеплять" операторы постановки и изъятия из очереди (навроде работы с потоками ввода-вывода С++). А для этого необходимо, чтобы операторы возвращали ссылку на объект-очередь, а в параметрах принимали ссылку на элемент. Вроде бы в библиотеке контейнеров Qt я уже видел что-то подобное.
Сделал так:
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
#include <iostream>
#include <stdexcept>
#include <cstdlib>
 
namespace my
{
    template<class T>
    class queue
    {
    
    public:
        
        queue();
        ~queue();
        
        queue<T>& operator << (const T& elem);
        queue<T>& operator >> (T& elem);
        
        bool empty() const;
        
    private:
    
        struct node
        {
            T       data;
            node*   next;
            
            node(const T& elem)
                : data(elem), next(NULL) {}
        };
        
        node*   m_pnHead;
        node*   m_pnTail;
    };
    
    template<class T>
    queue<T>::queue()
        : m_pnHead(NULL), m_pnTail(NULL) {}
        
    template<class T>
    queue<T>::~queue()
    {
        while(m_pnHead)
        {
            node* delnode = m_pnHead;
            m_pnHead = m_pnHead->next;
            delete delnode;
            delnode = NULL;
        }
    }
    
    template<class T>
    queue<T>& queue<T>::operator << (const T& elem)
    {
        node* newnode = new node(elem);
        if(!m_pnTail)
            m_pnHead = newnode;
        else
            m_pnTail->next = newnode;
        m_pnTail = newnode;
        return *this;
    }
    
    template<class T>
    queue<T>& queue<T>::operator >> (T& elem)
    {
        if(!m_pnHead)
            throw std::runtime_error("queue is already empty!");
        node* delnode = m_pnHead;
        m_pnHead = m_pnHead->next;
        
        elem = delnode->data;
        delete delnode;
        delnode = NULL;
        return *this;
    }
    
    template<class T>
    bool queue<T>::empty() const
    {
        return m_pnHead == NULL;
    }
}
 
int main()
{
    my::queue<int> iqueue;
    iqueue << 4 << 6 << 8; // Ставим элементы в очередь
    int a, b, c;
    iqueue >> a >> b >> c; // Вынимаем элементы из очереди
    std::cout << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
    return EXIT_SUCCESS;
}
PS. А вот то, что ты не определил деcтруктор - плохо!
0
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
17.10.2010, 17:28  [ТС] #3
Цитата Сообщение от Nameless One Посмотреть сообщение
PS. А вот то, что ты не определил деcтруктор - плохо!
На счет диструктора, да. Я просто пока тестировал. Мне как то не оч понятен ваш код. Можете как то помочь мой просто исправить)))
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 17:34 #4
Цитата Сообщение от robert19 Посмотреть сообщение
Можете как то помочь мой просто исправить)))
Зачем ты оператору >> передаешь адрес первого узла очереди? Он у тебя и так уже известен, хранится в переменной-члене pbeg (или this->pbeg, если указывать явно)
0
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
17.10.2010, 17:44  [ТС] #5
Цитата Сообщение от Nameless One Посмотреть сообщение
Зачем ты оператору >> передаешь адрес первого узла очереди? Он у тебя и так уже известен, хранится в переменной-члене pbeg (или this->pbeg, если указывать явно)
а что туда передавать нужно?
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 17:49 #6
Смотря какого поведения ты ожидаешь от оператора.
Если такого (overed - это заранее объявленный объект твоего класса):
C++
1
int i = overed >>;
(вот только, если я не ошибаюсь, нельзя переопределять арность оператора) то прототип оператора должен быть таким:
C++
1
int operator >>(); // вроде бы неправильно
А если такого:
C++
1
2
int i, j, k;
overed >> i >> j >> k;
то таким:
C++
1
Ocher& operator >>(int& val);
1
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
17.10.2010, 17:55  [ТС] #7
Что то вообще не понимаю(((
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 18:00 #8
Цитата Сообщение от robert19 Посмотреть сообщение
Что то вообще не понимаю(((
А ты постарайся. Ты вообще пробовал запускать мой пример?
0
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
17.10.2010, 18:05  [ТС] #9
Цитата Сообщение от Nameless One Посмотреть сообщение
А ты постарайся. Ты вообще пробовал запускать мой пример?
Нет. потому что мы так не учили как ты написал. И мне не понятно
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 18:07 #10
Цитата Сообщение от robert19 Посмотреть сообщение
Нет. потому что мы так не учили как ты написал. И мне не понятно
используй гугл, Люк, и смотри в сторону шаблонов
0
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
17.10.2010, 18:14  [ТС] #11
Разве нельзя мой подредактировать. Я просто не могу понять что там изменить нужно
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 18:18 #12
Цитата Сообщение от robert19 Посмотреть сообщение
Я просто не могу понять что там изменить нужно
А я уже написал, что нужно. И только не надо говорить, что
мы так не учили как ты написал. И мне не понятно
поскольку этот мой пост я писал, ориентируесь уже на твою версию программы.
0
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
17.10.2010, 18:22  [ТС] #13
да не я пытался так написать но выдает ошибки((
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 18:27 #14
Цитата Сообщение от robert19 Посмотреть сообщение
да не я пытался так написать но выдает ошибки((
Покажи, что написал, и какие ошибки выдает
0
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
17.10.2010, 18:35  [ТС] #15
Да все практически осталось то же самое. Только дописал диструктор
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 <string.h>
#include <iostream>
using namespace std;
class List{
private:
    struct Element{     // структура, задающая элемент списка
        int key;        // поле для хранения данных
        Element *next;  // указатель на следующий элемент
    };
    Element* pbeg;//начало очереди
    Element* pend;//конец очереди
public:
    List(){
        Element* pbeg = 0;
        Element* pend = 0;
    }
    int operator <<(int a);
    int operator >>(int &a);
    void print();
    ~List(){
        if(pbeg){
            pend=pbeg;
            while (pbeg)
                pbeg=pbeg->next;
            delete pend;
            pend=pbeg;
        }
    }
}
int List::operator << (int a){
    Element* ph = new Element;
    ph->key = a;
    ph->next = 0;
    if (*pend!=0){
        (*pend)->next = ph;
        *pend = ph;
    }
    else{
        *pbeg = ph;
        *pend = ph;
    }
    return 0;
}
 
int List::operator>>(int &a){//сюда ты предлагал вставить вот это List& operator >>(int& val);
    int d = pbeg->key;
    Element* ph = pbeg;
    pbeg = pbeg->next;
    delete ph;
    return d;
}
 
void List::print(){
    while (pbeg != 0){
        Element *ph = pbeg;
        pbeg = pbeg->next;
        cout<<" "<<ph->key;
    }
}
 
int main(){
    setlocale(LC_ALL,"Russian");
    List w;
    int b,a;
    while(true){
        system("cls");
        cout<<"1) Заполнить очередь"<<endl;
        cout<<"2) Вывести на экран"<<endl;
        cout<<"3) Удалить элемент"<<endl;
        cout<<"0) Выход"<<endl;
        cout<<"Ввод: "; cin>>b;
        if (b == 1){
            system("cls");
            cout<<"Введите значение: ";
            cin>>a;
            w<<a;
            cin.clear();
            fflush(stdin);
            continue;
        }
        if (b == 2){
            system("cls");
            cout<<"Список: ";
            w.print;//здесь ошибка (из за точки), хочу что бы распечаталсся список
            while (true){
                cout<<"\n0) Выход: ";
                int z; cin>>z;
                if (z == 0) break;
                cin.clear();
                fflush(stdin);
                continue;
            }
            cin.clear();
            fflush(stdin);
            continue;
        }
        if (b == 3){
            //Здесь не знаю как сделать что бы из очереди удалился первый элемент
        }
        system("cls");
        if (b == 0) break;
 
    }
 
    return 0;
}
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 18:44 #16
Замени в возвращаемом значении операторов int на List&, и в конце каждого из них пропиши
C++
1
return *this;
Замени 46 строку на
C++
1
a = pbeg->key;
Удаление первого элемента из очереди делай так:
C++
1
2
int b;
w >> b; // в b теперь хранится значение удаленного первого элемента очереди
Добавлено через 1 минуту
Цитата Сообщение от robert19 Посмотреть сообщение
C++
1
w.print;//здесь ошибка (из за точки), хочу что бы распечаталсся список
Забыл скобки:
C++
1
w.print();
0
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
17.10.2010, 18:44  [ТС] #17
error C2628: недопустимый "List" с последующим "int" (возможно, отсутствует ";")
error C2556: List List::operator <<(int): перегруженная функция отличается от "int List::operator <<(int)" только возвращаемым типом
error C2371: List::operator <<: переопределение; различные базовые типы
error C2678: бинарный "!=": не найден оператор, принимающий левый операнд типа "List::Element" (или приемлемое преобразование отсутствует)
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\system_error(432): или "bool std::operator !=(const std::error_condition &,const std::error_code &)"
1> при попытке сопоставить список аргументов "(List::Element, int)"
error C2819: тип "List::Element" не имеет перегруженный "operator ->"
error C2232: ->List::Element::next: левый операнд имеет тип "struct", используйте "."
error C2679: бинарный "=": не найден оператор, принимающий правый операнд типа "List::Element *" (или приемлемое преобразование отсутствует)
error C2679: бинарный "=": не найден оператор, принимающий правый операнд типа "List::Element *" (или приемлемое преобразование отсутствует)
error C2679: бинарный "=": не найден оператор, принимающий правый операнд типа "List::Element *" (или приемлемое преобразование отсутствует)
error C2440: return: невозможно преобразовать "int" в "List &"
error C2264: List::operator <<: ошибка в определении или объявлении функции; функция не вызвана
error C2088: <<: недопустимо для class
error C3867: List:rint: в вызове функции отсутствует список аргументов; используйте "&List:rint" для создания указателя на член
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 18:50 #18
robert19, а теперь покажи, как ты объявил и описал операторы
0
robert19
27 / 27 / 7
Регистрация: 26.03.2010
Сообщений: 305
17.10.2010, 18:57  [ТС] #19
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 <string.h>
#include <iostream>
using namespace std;
class List{
private:
    struct Element{     // структура, задающая элемент списка
        int key;        // поле для хранения данных
        Element *next;  // указатель на следующий элемент
    };
    Element* pbeg;//начало очереди
    Element* pend;//конец очереди
public:
    List(){
        Element* pbeg = 0;
        Element* pend = 0;
    }
    int operator <<(int a);
    List& operator >>(List&);
    void print();
    ~List(){
        if(pbeg){
            pend=pbeg;
            while (pbeg)
                pbeg=pbeg->next;
            delete pend;
            pend=pbeg;
        }
    }
}
int List::operator << (int a){// если поменять на List&  List::operator <<  (int a)... Выдает ошибку
    Element* ph = new Element;
    ph->key = a;
    ph->next = 0;
    if (pend!=0){
        pend->next = ph;
        pend = ph;
    }
    else{
        pbeg = ph;
        pend = ph;
    }
    return *this;//тут ругается
}
 
List& List::operator>>(List&){
    int a = pbeg->key;
    Element* ph = pbeg;
    pbeg = pbeg->next;
    delete ph;
    return *this;
}
 
void List::print(){
    while (pbeg != 0){
        Element *ph = pbeg;
        pbeg = pbeg->next;
        cout<<" "<<ph->key;
    }
}
 
int main(){
    setlocale(LC_ALL,"Russian");
    List w;
    int b,a;
    while(true){
        system("cls");
        cout<<"1) Заполнить очередь"<<endl;
        cout<<"2) Вывести на экран"<<endl;
        cout<<"3) Удалить элемент"<<endl;
        cout<<"0) Выход"<<endl;
        cout<<"Ввод: "; cin>>b;
        if (b == 1){
            system("cls");
            cout<<"Введите значение: ";
            cin>>a;
            w<<a;
            cin.clear();
            fflush(stdin);
            continue;
        }
        if (b == 2){
            system("cls");
            cout<<"Список: ";
            w.print();//здесь ошибка (из за точки), хочу что бы распечаталсся список
            while (true){
                cout<<"\n0) Выход: ";
                int z; cin>>z;
                if (z == 0) break;
                cin.clear();
                fflush(stdin);
                continue;
            }
            cin.clear();
            fflush(stdin);
            continue;
        }
        if (b == 3){
            //Здесь не знаю как сделать что бы из очереди удалился первый элемент
        }
        system("cls");
        if (b == 0) break;
 
    }
 
    return 0;
}
error C2628: недопустимый "List" с последующим "int" (возможно, отсутствует ";")
error C2556: List List::operator <<(int): перегруженная функция отличается от "int List::operator <<(int)" только возвращаемым типом
error C2371: List::operator <<: переопределение; различные базовые типы
error C2264: List::operator <<: ошибка в определении или объявлении функции; функция не вызвана
error C2088: <<: недопустимо для class
0
Nameless One
Эксперт С++
5785 / 3434 / 351
Регистрация: 08.02.2010
Сообщений: 7,448
17.10.2010, 19:23 #20
Разберем ошибки:
Цитата Сообщение от robert19 Посмотреть сообщение
если поменять на List& List::operator << (int a)... Выдает ошибку
Нужно читать внимательней:
Цитата Сообщение от Nameless One Посмотреть сообщение
Замени в возвращаемом значении операторов int на List&, и в конце каждого из них пропиши
C++
1
return *this;
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// если поменять на List&  List::operator <<  (int a)... Выдает ошибку
// и где же здесь ты поменял int на List& ?
int List::operator << (int a){
        Element* ph = new Element;
        ph->key = a;
        ph->next = 0;
        if (pend!=0){
                pend->next = ph;
                pend = ph;
        }
        else{
                pbeg = ph;
                pend = ph;
        }
        return *this;//тут ругается - ну ясен пень, *this - это ссылка на List, а в возвращаемом значении прописано int
}
Надо так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
List& List::operator << (int a){// если поменять на List&  List::operator <<  (int a)... Выдает ошибку
        Element* ph = new Element;
        ph->key = a;
        ph->next = 0;
        if (pend!=0){
                pend->next = ph;
                pend = ph;
        }
        else{
                pbeg = ph;
                pend = ph;
        }
        return *this;
}
Пошли дальше...
C++
1
2
3
4
5
6
7
List& List::operator>>(List&){
 int a = pbeg->key; 
 Element* ph = pbeg;
 pbeg = pbeg->next;
 delete ph;
 return *this;
}
Было написано:
Цитата Сообщение от Nameless One Посмотреть сообщение
Замени 46 строку на
C++
1
a = pbeg->key;
А ты что сделал? Ты заменил тип аргумента оператора, и сделал a локальной. Зачем? Надо так:
C++
1
2
3
4
5
6
7
List& List::operator>>(int& a){
 a = pbeg->key; 
 Element* ph = pbeg;
 pbeg = pbeg->next;
 delete ph;
 return *this;
}
И не забудь соответственно изменить объявления операторов внутри класса
0
17.10.2010, 19:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.10.2010, 19:23
Привет! Вот еще темы с решениями:

Перегрузка операций
Добрый день форумчане, помогите решить задачку Перегрузить 8 операторов для...

Перегрузка операций
#include &lt;iostream&gt; using namespace std; class chislo { public:...

Перегрузка операций
Добрый день! Задание простенькое но не могу решить так как не получается...

ПЕРЕГРУЗКА ОПЕРАЦИЙ
Не знаю как делать задания( Прошу помощи 1) Ввести класс для работы с...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru