Перегрузка операторов - уточнение

330
18 января 2018, 21:18

Почему вот это называется перегрузкой оператора? cout разве не выводит пользовательские типы БЕЗ перегрузки?

// overload_date.cpp  
// compile with: /EHsc  
#include <iostream>  
using namespace std;  
class Date  
{  
    int mo, da, yr;  
public:  
    Date(int m, int d, int y)  
    {  
        mo = m; da = d; yr = y;  
    }  
    friend ostream& operator<<(ostream& os, const Date& dt);  
};  
ostream& operator<<(ostream& os, const Date& dt)  
{  
    os << dt.mo << '/' << dt.da << '/' << dt.yr;  
    return os;  
}  
int main()  
{  
    Date dt(5, 6, 92);  
    cout << dt;  
}  
Answer 1

А что, в стандартном С++ есть оператор

ostream& operator<<(ostream& os, const Date& dt) 

т.е. для вывода Date?

Нет, его нет. Он создается программистом для своего пользовательского типа.

Если я определю, например, функцию

myClass sqrt(myClass& m);

которая будет выполнять какие-то свои действия - вы же не будете говорить - разве sqrt не считает квадратный корень без перегрузки?

Но, кстати, cout выводит пользовательские типы, вообще говоря, с использованием перегрузки.

На всякий случай напомню, что такое перегрузка...

Под перегрузкой функции понимается, определение нескольких функций (две или больше) с одинаковым именем, но различными параметрами. Наборы параметров перегруженных функций могут отличаться порядком следования, количеством, типом.

Answer 2

Если поля вашего класса являются доступными извне и вам не лень везде писать руками

std::cout << d.mo << d.da << d.yr << std::endl;

то с точки зрения удобства и/или сокращения длины кода вам действительно не нужен перегруженный оператор << для вашего Date.

Однако ценность такого оператора далеко не сводится к сокращению длины записи. Более того, ценность такого оператора заключается в первую очередь именно в том, что он унифицирует интерфейс ввода-вывода вашего класса с принятым в стандартной библиотеке интерфейсом. После переопределения оператора << ваш класс становится совместимым с многими существующими средствами форматированного вывода стандартной библиотеки.

Например, пользуясь стандартным алгоритмом std::copy вы сможете вывести на выход массив ваших объектов Date через std::ostream_iterator вот так

Date date[] = { ... };
std::copy(std::begin(date), std::end(date), std::ostream_iterator<Date>(std::cout, "\n"));

но только если для вашего Date определен оператор <<.

(Я вам уже писал именно об этом.)

Answer 3
cout может вывести  данные класса, если они открытые, и для них уже определен оператор вывода. Например:
class Date  
{  
public:
    int mo, da, yr;   
    Date(int m, int d, int y) : mo(m), da(d), yr(y) {} 
};

или это тоже самое, что

struct Date  
{  
    int mo, da, yr;   
    Date(int m, int d, int y) : mo(m), da(d), yr(y) {} 
};

и можно спокойно написать

 Date d(1, 1, 2000);
  cout << d.mo << d.da << d.yr; 
READ ALSO
expected &#39;,&#39; or &#39;;&#39; before &#39;do&#39; Ошибка при компиляции

expected ',' or ';' before 'do' Ошибка при компиляции

Начинаю компилировать и выходит ошибка кода, вот: (недоделал пока)

320
Агрегация - доступ к членам класса

Агрегация - доступ к членам класса

Имеет ли при агрегации класс доступ к protected-полям другого, агрегированного класса?

368
отношение между классами

отношение между классами

Можно ли в классе С выполнить расчет int a / int b и записать результат в переменную класса С int c?

370
Перегрузка оператора в классе

Перегрузка оператора в классе

Не получается перегрузить оператор сравнения "<"Использую Qt

394