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

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

Войти
Регистрация
Восстановить пароль
 
 
Neumann1
0 / 0 / 0
Регистрация: 20.09.2012
Сообщений: 30
#1

Переопределить оператор << в классе - C++

08.10.2012, 17:54. Просмотров 839. Ответов 17
Метки нет (Все метки)

Добрый день.

Не пойму как переопределить оператор << для моего класса

Пробую так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
class MyClass
{
public:
 
    MyClass(){}
 
    ~MyClass(){}
 
    std::ostream& operator<< (std::ostream sto, MyClass mycl) 
    {
         return sto << "operator <<";
    }
 
};
 
// в функции main
MyClass mycl;
std::cout << mycl;
Пишут ошибку
no match for 'operator<<' in 'std::cout << mycl'

Не подскажите что не так?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.10.2012, 17:54
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Переопределить оператор << в классе (C++):

Как переопределить функцию func2 в классе B - C++
class A { A() {} и тд. public: functions.................... virtual void func1() = 0; class littleClass { ...

Как переопределить перегруженную функцию в производном классе? - C++
Как переопределить перегруженную функцию в производном классе? #include &lt;iostream&gt; class Number { public: virtual Number*...

Как можно переопределить <обобщенный аргумент> в обобщенном классе - C++
допустим есть что то простое // // #ifndef Print_HPP #define Print_HPP

Как переопределить оператор ++ типа char? - C++
Добрий день Хочу спросить возможно ли как-то переопредилить оператор ++ типа char?

Можно ли переопределить функцию-член в унаследованном классе, не объявляя её виртуальной в родительском? - C++
Предположим, есть абстрактный класс Worker. class Worker { protected: char *myName; int value; private: ...

Создать класс Str (символьная строка). Переопределить оператор присвоения. - C++
Помогите решить с обяснениями. Создать класс Str (символьная строка). Переопределить оператор присвоения.

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
08.10.2012, 17:57 #2
вынеси перегрузку из класса
0
wtf?
19 / 19 / 0
Регистрация: 03.10.2010
Сообщений: 48
08.10.2012, 17:57 #3
Если использовать твой тогда нужно писать так:
C++
1
mycl << std::cout;
Если хочешь нормальный тогда делай глобальную перегрузку, и если ей нужен доступ к закрытым членам класса обьявляй её френдом
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
08.10.2012, 17:58 #4
C++
1
2
3
4
5
    friend std::ostream& operator<< (std::ostream& sto, const MyClass& mycl) 
    {
         sto << "operator <<";
         return sto;
    }
fixed.
0
Neumann1
0 / 0 / 0
Регистрация: 20.09.2012
Сообщений: 30
08.10.2012, 18:20  [ТС] #5
Вот как оно значит.
А скажите - этот нюанс с френдом касается только перегрузки операторов классов? Можете дать ссылку на стандарт, где об этом написано?
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
08.10.2012, 18:31 #6
Neumann1, Аж на стандарт? оО
Операторы могут быть унарные/бинарные/n-арные (оператор () ). В частности оператор << - бинарный оператор, если определять в классе - можно передать только один свой параметр, ибо первый параметр в любом случае будет this, если свободная функция соответственно два параметра (ссылка на поток + константная ссылка на объект класса). Если friend - единственное отличие от свободной - имеет доступ к закрытой части класса. Собственно в стандарте это все естественно описано, просто откройте стандарт и почитайте, в частности разделы 9-13.
1
Neumann1
0 / 0 / 0
Регистрация: 20.09.2012
Сообщений: 30
08.10.2012, 22:49  [ТС] #7
Прочитал ваш комментарий, потом прочитал про friend у Страуструпа (не в стандарте, а в "Язык прог-ия С++"), все равно до конца не пойму. А хочется понять.
Вот эта часть книги (но другими словами - наверное другое издание)
Следовательно операция, изменяющая состояние объекта класса,
должна быть членом или глобальной функцией с параметром-ссылкой
без спецификации const. Операции над основными типами, которые
требуют в качестве операндов адреса (=, *, ++ и т.д.),
для пользовательских типов естественно определять как члены.
Обратно, если требуется неявное преобразование типа для всех
операндов некоторой операции, то реализующая ее функция должна
быть не членом, а глобальной функцией и иметь параметр типа ссылки
со спецификацией const или нессылочный параметр. Так обычно обстоит
дело с функциями, реализующими операции, которые для основных
типов не требуют адресов в качестве операндов (+, -, || и т.д.).
под глобальными здесь имеются ввиду френды, там потом в примерах так.
У меня в книге лучше написано, но здесь тоже самое.

Но я не пойму соль.
Вот если я объявлю функцию-член например
C++
1
2
3
4
5
6
7
8
class MyClass
{
 
//
     void f(int arg1, char arg2){}
//
 
}
то никаких проблем, что у функции-члена два аргумента нет! Всё норм.
А если именно переопределяю оператор, то я должен смотреть - бинарный он или унарный (соответственно два или один аргумент). Почему? Почему не могу переопределить оператор с двумя аргументами как функцию-член?

Я не хочу принимать как данность, я хочу понять причину.
0
AnreyKazakov
Заблокирован
08.10.2012, 23:37 #8
Буквально на днях в книжке читал...
При определении оператора не может быть изменен ни его приоритет, ни порядок, ни количество операндов, тут же оговорка, что порядок выполненеия || и && не предсказуем, видимо undefinit или как там я не знаю англ... ну и наверно еще много оговорок всяк разных...
А вот с чем связана такая данность для самого загадка.... Но больше конечно бесят всякие вот такие неопределенности, в особенности i+=i+ ++i; всякая такая белеберда, просто бесит, ибо х з что выдаст компиль.
0
Neumann1
0 / 0 / 0
Регистрация: 20.09.2012
Сообщений: 30
09.10.2012, 10:07  [ТС] #9
типа такого?)
i = i++ + ++i
а мне нравится - как спортивный интерес.
Да, в разных компиляторах по разному, undefined behavior вроде.

А по теме - вопрос еще открыт! )
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
09.10.2012, 10:37 #10
Neumann1, Так указано в стандарте. Так решили авторы языка. Так логично. У каждого оператора, кроме () есть арность, арность нарушать/переопределять нельзя.
0
Neumann1
0 / 0 / 0
Регистрация: 20.09.2012
Сообщений: 30
09.10.2012, 10:40  [ТС] #11
Не, если они так решили, то я не против. Но я не понимаю, почему логично) почему?
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
09.10.2012, 11:26 #12
Neumann1, Ну. Кхм. Вот есть у нас оператор присваивания. В чем логика, если он будет не бинарным? Есть у нас оператор инкремента, в чем логика если он будет не унарным? Оператор *, -> аналогично.
0
Neumann1
0 / 0 / 0
Регистрация: 20.09.2012
Сообщений: 30
09.10.2012, 11:39  [ТС] #13
Не, то что какой-то оператор унарный или бинарный, это я понимаю. Оператор << естественно бинарный. Но почему эта его бинарность обязывает меня реализовать его как friend?
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
09.10.2012, 12:01 #14
Neumann1, Потому что первый параметр функции-члена - указатель на объект данного класса. Нету обязательства реализовывать его как friend. Бывает нужно, чтобы оператор вывода в поток был именно членом класса. Но если первым параметром должен быть не объект данного класса, а к примеру ostream - тогда либо свободная функция, либо friend.
0
Neumann1
0 / 0 / 0
Регистрация: 20.09.2012
Сообщений: 30
09.10.2012, 13:13  [ТС] #15
ForEveR,
Потому что первый параметр функции-члена - указатель на объект данного класса."
Вот этот момент я и не понимаю - где этот this и почему он в функциях-членах.

Вот два примера:

void f(int arg1, char arg2)

std::ostream& operator<< (std::ostream& sto, const MyClass& mycl)

Где в обоих случаях this? Разве первый параметр не является потоком вывода?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.10.2012, 13:13
Привет! Вот еще темы с ответами:

Перегруженный оператор = в классе String - C++
Перегруженный оператор = почему то не работает, не могу разобраться в чем проблема, вроде все норм. String &amp;String::operator=(const...

не работает префиксный оператор в классе - C++
Проблема : не работает &quot;++plus&quot; в &quot;void ClassB::count()&quot; Есть вариант решить это так : поменять &quot;private&quot; на &quot;protected&quot; в обоих классах...

Оператор вывода в производном классе - C++
Как из производного класса вызвать перегруженный оператор вывода из базового класса? Я показал в комментарии где нужно это вставить ...

Шаблонный оператор присваивания в шаблонном классе - C++
Почему, в таком коде, срабатывает оператор присваивания по умолчанию? template &lt;class T&gt; class A { T x; public: A(T...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.10.2012, 13:13
Ответ Создать тему
Опции темы

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