Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
1 / 1 / 0
Регистрация: 20.09.2012
Сообщений: 30
1

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

08.10.2012, 17:54. Просмотров 1736. Ответов 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.10.2012, 17:54
Ответы с готовыми решениями:

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

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

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

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

17
74 / 37 / 3
Регистрация: 23.09.2012
Сообщений: 408
08.10.2012, 17:57 2
вынеси перегрузку из класса
0
19 / 19 / 13
Регистрация: 03.10.2010
Сообщений: 48
08.10.2012, 17:57 3
Если использовать твой тогда нужно писать так:
C++
1
mycl << std::cout;
Если хочешь нормальный тогда делай глобальную перегрузку, и если ей нужен доступ к закрытым членам класса обьявляй её френдом
0
В астрале
Эксперт С++
8030 / 4787 / 655
Регистрация: 24.06.2010
Сообщений: 10,558
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
1 / 1 / 0
Регистрация: 20.09.2012
Сообщений: 30
08.10.2012, 18:20  [ТС] 5
Вот как оно значит.
А скажите - этот нюанс с френдом касается только перегрузки операторов классов? Можете дать ссылку на стандарт, где об этом написано?
0
В астрале
Эксперт С++
8030 / 4787 / 655
Регистрация: 24.06.2010
Сообщений: 10,558
08.10.2012, 18:31 6
Neumann1, Аж на стандарт? оО
Операторы могут быть унарные/бинарные/n-арные (оператор () ). В частности оператор << - бинарный оператор, если определять в классе - можно передать только один свой параметр, ибо первый параметр в любом случае будет this, если свободная функция соответственно два параметра (ссылка на поток + константная ссылка на объект класса). Если friend - единственное отличие от свободной - имеет доступ к закрытой части класса. Собственно в стандарте это все естественно описано, просто откройте стандарт и почитайте, в частности разделы 9-13.
1
1 / 1 / 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
Заблокирован
08.10.2012, 23:37 8
Буквально на днях в книжке читал...
При определении оператора не может быть изменен ни его приоритет, ни порядок, ни количество операндов, тут же оговорка, что порядок выполненеия || и && не предсказуем, видимо undefinit или как там я не знаю англ... ну и наверно еще много оговорок всяк разных...
А вот с чем связана такая данность для самого загадка.... Но больше конечно бесят всякие вот такие неопределенности, в особенности i+=i+ ++i; всякая такая белеберда, просто бесит, ибо х з что выдаст компиль.
0
1 / 1 / 0
Регистрация: 20.09.2012
Сообщений: 30
09.10.2012, 10:07  [ТС] 9
типа такого?)
i = i++ + ++i
а мне нравится - как спортивный интерес.
Да, в разных компиляторах по разному, undefined behavior вроде.

А по теме - вопрос еще открыт! )
0
В астрале
Эксперт С++
8030 / 4787 / 655
Регистрация: 24.06.2010
Сообщений: 10,558
09.10.2012, 10:37 10
Neumann1, Так указано в стандарте. Так решили авторы языка. Так логично. У каждого оператора, кроме () есть арность, арность нарушать/переопределять нельзя.
0
1 / 1 / 0
Регистрация: 20.09.2012
Сообщений: 30
09.10.2012, 10:40  [ТС] 11
Не, если они так решили, то я не против. Но я не понимаю, почему логично) почему?
0
В астрале
Эксперт С++
8030 / 4787 / 655
Регистрация: 24.06.2010
Сообщений: 10,558
09.10.2012, 11:26 12
Neumann1, Ну. Кхм. Вот есть у нас оператор присваивания. В чем логика, если он будет не бинарным? Есть у нас оператор инкремента, в чем логика если он будет не унарным? Оператор *, -> аналогично.
0
1 / 1 / 0
Регистрация: 20.09.2012
Сообщений: 30
09.10.2012, 11:39  [ТС] 13
Не, то что какой-то оператор унарный или бинарный, это я понимаю. Оператор << естественно бинарный. Но почему эта его бинарность обязывает меня реализовать его как friend?
0
В астрале
Эксперт С++
8030 / 4787 / 655
Регистрация: 24.06.2010
Сообщений: 10,558
09.10.2012, 12:01 14
Neumann1, Потому что первый параметр функции-члена - указатель на объект данного класса. Нету обязательства реализовывать его как friend. Бывает нужно, чтобы оператор вывода в поток был именно членом класса. Но если первым параметром должен быть не объект данного класса, а к примеру ostream - тогда либо свободная функция, либо friend.
0
1 / 1 / 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
В астрале
Эксперт С++
8030 / 4787 / 655
Регистрация: 24.06.2010
Сообщений: 10,558
09.10.2012, 13:46 16
Neumann1, Эм.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class C
{
public:
   // Практически эквивалентно void f(C* const this)
   void f();
   // Вообщем-то бессмысленно, ибо эквивалентно
   // std::ostream& operator << (C* const this, const C&);
   std::ostream& operator << (const C&);
   // Никакого this тут нет. Тоже самое, что свободная функция,
   // но имеет право доступа не только в паблик данным класса.
   friend std::ostream& operator << (std::ostream&, const C&);
};
 
// Обычная свободная функция.
std::ostream& operator << (std::ostream&, const C&);
1
1 / 1 / 0
Регистрация: 20.09.2012
Сообщений: 30
09.10.2012, 14:53  [ТС] 17
Вот он, краеугольный камень.
Когда вы впервые сказали про this, я подумал о чем-то таком.
Теперь я понял. Буду знать - если функция-член, то невидимый первый параметр - константный указатель на класс.
0
Эксперт С++
5042 / 3103 / 271
Регистрация: 11.11.2009
Сообщений: 7,047
09.10.2012, 20:59 18
Neumann1, весь топик не читал, но прозвучал вопрос "почему именно френд?" Так вот, не обязательно. Если оператор << сможет до всех необходимых ему данных через публичные методы (проще говоря, через интерфейс) класса - то делать его другом не нужно. Френд тут нужен для того, чтобы напрямую обращаться к сокрытым полям или методам класса, т.е., по большому счёту, нарушать инкапсуляцию.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.10.2012, 20:59

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

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

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

Как создать виртуальный поток и переопределить оператор <<?
Виртуальный то есть имеется ввиду не файловый и не строковый и не консольный. Впрочем, создание...

Перегруженный оператор = в классе String
Перегруженный оператор = почему то не работает, не могу разобраться в чем проблема, вроде все норм....


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

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

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