同时重载流插入和自减运算符 输出时报错

同时重载流插入和自减运算符 输出时报错 请问这是什么问题?

代码如下:

#include <bits/stdc++.h>
using namespace std;

//.h
class Date {
public:
    int Year;
    int Month;
    int Day;
public:
    Date(int year = 0, int month = 0, int day = 0);
    friend ostream& operator<<(ostream&, Date&);
    friend istream& operator>>(istream&, Date&);
    Date operator--();//重载前置自减
    Date operator--(int);//重载后置自减
};

//.cpp
Date::Date(int year, int month, int day) {
    Year = year;
    Month = month;
    Day = day;
}

ostream& operator<<(ostream& output, Date& d) {
    output << "Year:" << d.Year << '\n' << "Month:" << d.Month << '\n' << "Day:" << d.Day << endl;
    return output;
}

istream& operator>>(istream& input, Date& d) {
    cout << "请依次输入年、月、日的值:";
    input >> d.Year >> d.Month >> d.Day;
    return input;
}

Date Date::operator--() {
    //暂不考虑实际情况的复杂处理
    --Day;
    return *this;
}

Date Date::operator--(int) {
    //暂不考虑实际情况的复杂处理
    Date tmp(*this);
    Day--;
    return tmp;
}

//main
int main() {
    Date d(1, 2, 3);
    Date d2;
    cout  << (d--);

    return 0;
}

错误信息:

img


重载没有问题:

img

问题出在流插入运算符的重载上。在重载流插入运算符时,应该返回一个const类型的引用,以避免修改对象的值。修改流插入运算符的重载函数如下:

ostream& operator<<(ostream& output, Date& d) {
    output << "Year:" << d.Year << '\n' << "Month:" << d.Month << '\n' << "Day:" << d.Day << endl;
    return output;
}

ostream& operator<<(ostream& output, const Date& d) {
    output << "Year:" << d.Year << '\n' << "Month:" << d.Month << '\n' << "Day:" << d.Day << endl;
    return output;
}

同时,如果要在输出之后执行自减操作,应该先将对象的值输出,再进行自减操作。修改main函数的代码如下:

int main() {
    Date d(1, 2, 3);
    Date d2;
    cout << d;
    d--;
    return 0;
}

这样,即可正确输出对象的值并执行自减操作。

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
在你的代码中,对于自减运算符 -- 的重载,你分别定义了前置自减和后置自减两个版本。在这两个版本中,你都对 Day 成员变量进行了自减操作,但是在后置自减版本中,你还需要返回原始的对象值,因此你使用了一个临时变量 tmp 来保存原始的对象值。

在你的 main() 函数中,你使用了后置自减运算符来对 d 进行自减操作,即 d--。然而,由于你并没有将自减操作后的结果赋值给任何变量,因此编译器会认为你并不关心这个结果,而只是想要输出 d 的值。因此,编译器会尝试调用 ostream& operator<<(ostream&, Date&) 来输出 d 的值。然而,由于后置自减运算符返回的是一个临时变量,而不是 d 的引用,因此编译器无法将其转换为 Date& 类型,从而导致了错误。

要解决这个问题,你可以将后置自减运算符的返回类型改为 Date&,并将 tmp 改为一个成员变量来保存原始的对象值。这样,后置自减运算符就可以返回 *this 的引用了,从而解决了类型转换的问题。修改后的代码如下:

class Date {
public:
    int Year;
    int Month;
    int Day;
public:
    Date(int year = 0, int month = 0, int day = 0);
    friend ostream& operator<<(ostream&, Date&);
    friend istream& operator>>(istream&, Date&);
    Date& operator--();//重载前置自减
    Date operator--(int);//重载后置自减
private:
    Date tmp;//成员变量,用于保存原始对象值
};
 
Date Date::operator--(int) {
    tmp = *this;//保存原始对象值
    Day--;
    return tmp;//返回原始对象值
}
 
Date& Date::operator--() {
    --Day;
    return *this;
}

这样,你就可以正确地使用后置自减运算符了,而不会出现类型转换错误。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢