实现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
相关产品推荐
相关产品推荐

