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

ошибка с перегрузкой операции - C++

Восстановить пароль Регистрация
 
No10
 Аватар для No10
30 / 28 / 2
Регистрация: 03.06.2010
Сообщений: 465
19.06.2012, 23:05     ошибка с перегрузкой операции #1
Долго сижу и никак не могу понять в чём ошибка. Вот 3 файла. Они подключены правильно и работают.
main.cpp

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
#include <iostream>
#include <iomanip>
#include <windows.h>
#include <math.h>
#include "string2.h"
 
using namespace std;
 
char bufRus[256];
char* Rus(const char* text) {
      CharToOem(text, bufRus);
      return bufRus;
}
 
int main()
{
    Date d1, d2(2, 24, 1995), d3(0, 99, 8045);
    cout << Rus("d1 равен: ") << d1 << endl;
    cout << Rus("d2 равен: ") << d2 << endl;
    cout << Rus("d3 равен: ") << d3 << endl;
 
    cout << Rus("d2 += 7 равно: ") << (d2 += 7) << endl << endl;
 
    Date d4(19, 6, 2012);
    cout << Rus("d4 равен: ") << d4 << endl;
    cout << "d4++ = " << ++d4 << endl; // сдесь ошибка как утверждает компилятор
 
    system("pause");
    return 0;
}


string2.h
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
#ifndef STRING2_H
#define STRING2_H
 
#include <iostream>
 
using namespace std;
 
class Date {
        friend ostream &operator<<(ostream &output, Date &);
    public:
        Date(int m = 1, int d = 1, int Y = 1995);
 
        void setDate(int, int, int);
        Date operator++();
        Date operator++(int);
        Date &operator+=(int);
 
        int leapYear(int);
        int endOfMonth(int);
    private:
        int month;
        int day;
        int year;
        static int days[];
        void helpIncrement();
};
 
#endif // STRING2_H
string2.cpp

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
#include <iostream>
#include <iomanip>
#include <windows.h>
#include <math.h>
#include "string2.h"
 
using namespace std;
 
char bufRus2[256];
char* Rus2(const char* text) {
      CharToOem(text, bufRus2);
      return bufRus2;
}
 
int Date::days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
Date::Date(int m, int d, int y) { setDate(m, d, y); }
 
void Date::setDate(int mm, int dd, int yy)
{
    month = (mm >= 1 && mm <= 12) ? mm : 1;
    year = (yy >= 1900 && yy <= 2100) ? yy : 1995;
 
    if (month == 2 && leapYear(year))
        day = (dd >= 1 && dd <= 29) ? dd : 1;
    else
        day = (dd >= 1 && dd <= days[month]) ? dd : 1;
}
 
Date Date::operator++ ()
{
    helpIncrement();
    return *this; // возвращаем не ссылку, а значение
}
 
Date Date::operator++(int)
{
    Date temp = *this;
    helpIncrement();
    return temp;
}
 
Date &Date::operator+= (int addInitionalDays)
{
    for (int i = 0; i <= addInitionalDays; i++)
        helpIncrement();
 
    return *this;
}
 
int Date::leapYear(int y)
{
    if (y % 400 == 0 || (y % 100 != 0 && y % 4 != 0))
        return 1;
    else
        return 0;
}
 
int Date::endOfMonth(int d)
{
    if (month == 2 && leapYear(year))
        return d == 29;
    else
        return d == days[month];
}
 
void Date::helpIncrement()
{
    if (endOfMonth(day) && month == 12) {
        day = 1;
        month = 1;
        year++;
    }
    else if (endOfMonth(day)) {
        day = 1;
        month++;
    }
    else day++;
}
 
ostream &operator<< (ostream &output,Date &d)
{
    static char *monthName[13] = {"", "Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Сентября", "Октября", "Ноября", "Декабря"};
    output << d.day << " " << Rus2(monthName[d.month]) << " " << d.year;
    return output;
}

А ошибка собсвенно одна:
C++
1
2
 C++\well\main.cpp|26|error: no match for 'operator<<' in 'std::operator<< [with _Traits = ...тра та та ещё на киллометр
||=== Build finished: 1 errors, 0 warnings ===|
Я работаю с книгой и это учебный пример. Дела с ним незаладились сразу.
Я написал ostream &operator<< (ostream &output,Date &d), но в книге
было написано ostream &operator<< (ostream &output,const Date &d),
но огда программа говорила что переменный day и year private. Я убрал всё зврвботало до поры до времени, пока я не стал использовать
перегрженную операцию ++ как префикс, да и как постфикс она тоже не работала.
Пожалуйста кто может растолкуйте новичку код, и особенно зачем нужен был const почему с ним н получалось.
И ещё растолкуйте пожалуйста как функция helpIncrement(); не принимая ни одного параметра може присваивать значения приватным
переменным? ей же нужна ссылка на обьект класса? Очень нуждаюсь в помощи. Заранее спасибо!
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.06.2012, 23:54     ошибка с перегрузкой операции #2
C++
1
2
3
4
5
Date d;
d.helpIncrement();
// Функция helpIncrement является методом класса. При вызове метода ему неявно передается
// указатель на объект, для которого она вызывается. В данном случае внутри метода
// this == &d;
Зря вы полную ошибку затрататорили якобы ненужной инфой. Там как раз было самое ценное.
Общее правило в с++: Если что-то в функции не должно изменятся, то это в функцию нужно передавать по константной ссылке, константному указателю или же по значению. Иначе могут быть
всякие сюрпризы вроде вашего.
В вашем случае у оператора такая сигнатура:
friend ostream &operator<<(ostream& output, Date&);
т.е. Date уходит по неконстантной ссылке. И вот что может быть:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
std::ostream& operator << (std::ostream& output, Date& date);
 
void PrintDate(std::ostream& out, const Date& date)
{
   // Тут представте что кто-то захотел использовать ваш класс и он дотошно 
   // везде, где надо расставлял слово const. У него не получится заиспользовать
   // ваш оператор. Он принимает неконстантную ссылку. Тут будет ошибка компиляции
}
 
Date ReturnDate()
{
  // Это просто функция, которая возвращает Date
}
 
Date d1;
const Date d2;
 
std::cout << d1; // ok
std::cout << d2; // Ошибка компиляции. Оператору нужна неконстантная ссылка.
std::cout << ReturnDate(); // Тут тоже ошибка компиляции.
// ReturnDate() возвращает "временный объект" типа Date. А временные объекты
// нельзя передавать в функции по неконстантной ссылке. По константной можно.
darkknight2008
 Аватар для darkknight2008
61 / 61 / 6
Регистрация: 16.10.2011
Сообщений: 200
19.06.2012, 23:55     ошибка с перегрузкой операции #3
const говорил о том, что переменная - это константа. Т.е. ее не изменяема. Это сделано для удобтва программиста, ведь если переменная передается по ссылке, то внутри функции эта переменная может измениться, а const как раз говорит, что переменная внутри функции меняться не может.
No10
 Аватар для No10
30 / 28 / 2
Регистрация: 03.06.2010
Сообщений: 465
20.06.2012, 09:50  [ТС]     ошибка с перегрузкой операции #4
да, но если я расставляю константы у меня компилятор говорит что переменные являются private вообще не пойму зачем он это говорит. Тоже самое говорила бы функция не являющаяся функцией элементом или дружественной функцией для класса Date. Мол те переменный которые она пытается изменить они private, ладно с такой функцией это логично. Но почему это выдает моя дружественная функция?
darkknight2008
 Аватар для darkknight2008
61 / 61 / 6
Регистрация: 16.10.2011
Сообщений: 200
20.06.2012, 11:23     ошибка с перегрузкой операции #5
Наверно ты меняешь заголовок самой функции, а объявление, что эта функция дружественная - нет.
Yandex
Объявления
20.06.2012, 11:23     ошибка с перегрузкой операции
Ответ Создать тему
Опции темы

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