You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现ostream插入运算符时遇‘Attempting to reference a deleted function’错误求助

解决ostream<<运算符的"Attempting to reference a deleted function"错误

我一眼就看到了两个关键问题导致你遇到这个错误,咱们一个个拆解:

1. ostream<<运算符的返回值错误(直接触发报错的核心原因)

你的运算符重载写成了:

friend ostream operator << (ostream& output, Date& obj) {
    output << wordmonth[month - 1] << " " << day << ". " << year;
    return output;
}

这里的问题在于返回值是ostream而不是ostream&。ostream类的拷贝构造函数是C++标准显式删除的,当你返回output时,编译器会尝试拷贝这个ostream对象,而这个操作是不允许的,所以直接抛出了"Attempting to reference a deleted function"错误。

修复方法很简单:把返回值改成ostream&,同时给obj加上const修饰(输出操作不应该修改对象,这样还能支持临时对象的输出):

friend ostream& operator << (ostream& output, const Date& obj) {
    // 注意要通过obj访问成员,后面会说为什么
    output << obj.wordmonth[obj.month - 1] << " " << obj.day << ". " << obj.year;
    return output;
}

2. Date类的成员设计错误(隐藏的逻辑Bug)

你把day、month、year都声明成了static,这意味着所有Date对象共享同一个日期值——比如你创建两个Date对象,修改其中一个的日期,另一个也会跟着变,这完全不符合Date类的设计初衷!而且你在运算符里直接访问day、month,本质上是访问静态成员,会导致所有对象输出的都是同一个日期。

修复这个问题,需要去掉成员变量的static修饰,同时修正所有成员函数的逻辑:

class Date {
private:
    // 去掉static,让每个对象拥有独立的日期成员
    int day;
    int month;
    int year;
public:
    static string wordmonth[];
    // 构造函数改为初始化当前对象的成员,而非静态成员
    Date(int d, int m, int y) : day(d), month(m), year(y) {}
    // 单参数构造函数给月、年默认值,避免未初始化
    Date(int d) : day(d), month(1), year(2024) {}
    // 默认构造函数也初始化成员
    Date() : day(1), month(1), year(2024) {}
    
    // 修改成员函数,操作当前对象的成员
    void setDay(int d) { this->day = d; }
    void setMonth(int m) { this->month = m; }
    void setYear(int y) { this->year = y; }
    // getter函数加const,支持const对象调用
    int getDay() const { return day; }
    int getMonth() const { return month; }
    int getYear() const { return year; }
    
    // 修正运算符重载,确保操作的是当前对象的成员
    Date& operator ++ () { // 前置++返回引用,效率更高
        day++;
        return *this;
    }
    Date operator ++ (int) { // 后置++返回临时对象
        Date temp = *this;
        ++day;
        return temp;
    }
    Date& operator -- () {
        day--;
        return *this;
    }
    Date operator -- (int) {
        Date temp = *this;
        --day;
        return temp;
    }
    Date operator - (const Date& v) const { // 右操作数和成员函数加const
        Date temp;
        temp.day = this->day - v.day;
        temp.month = this->month;
        temp.year = this->year;
        return temp;
    }
    
    // 修正后的ostream<<运算符
    friend ostream& operator << (ostream& output, const Date& obj) {
        output << obj.wordmonth[obj.month - 1] << " " << obj.day << ". " << obj.year;
        return output;
    }
};

另外,别忘了在类外部定义静态数组wordmonth(比如在cpp文件中):

// 初始化12个月份的英文名称
string Date::wordmonth[] = {
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
};

这样修改后,你的ostream<<运算符就能正常工作,同时Date类的逻辑也符合预期了。

内容的提问来源于stack exchange,提问作者Jaakko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:22:40