报错情况
在devc++中编写与C++类运算符重载时出现的了错误提示。
编译器定位到的错误位置为ios_base.h
下的
private:
ios_base(const ios_base&);
这行代码。
错误提示为:
[Error] ‘stdios_baseios_base(const stdios_base&)’ is private
报错分析
报错代码
#include<iostream>
using namespace std;
class Plural{
private:
double real,imag;
public:
Plural(double real = 0,double imag=0):real(real),imag(imag){}
friend istream operator>>(istream &in,Plural &a);
void show(){
cout << real << " " << imag << endl;
}
};
istream operator>>(istream &in,Plural &a){
in >> a.real >> a.imag;
return in;
}
int main(){
Plural p;
cin >> p;
p.show();
return 0;
}
分析
bug存在于第8行,
friend istream operator>>(istream &in,Plural &a)
即对右移运算符的重载。
我们注意到,这个函数的返回类型为istream
,这意味着当一个istream
的引用in
作为参数传入后,在函数体中进行了运算后,函数返回的结果不再是in
,而是in
的一个副本。
举个例子:
int fun(int &x){
return x;
}
对于这个fun函数,如果我们对这个函数的返回值进行修改,并不会对x本身的值有影响。因为fun函数在返回时进行了值的拷贝,我们修改的是副本的值,而非x本身。
同样的,对于
friend istream operator>>(istream &in,Plural &a)
函数返回的并不是in对象本身,而是进行了拷贝,返回了in对象的一个副本。
而我们知道,对于
cin >> a >> b;
它操作可以理解为
operator>>(operator>>(cin,a),b)
cin
对象在遇到连续多个>>
时,会在嵌套调用operator>>
时被依次地作为参数传入,此时传入的应该是cin
对象本身,而不应该是cin
对象的一个副本。
代码修正
综上所述,我们应该我们应该把
friend istream operator>>(istream &in,Plural &a)
改为
friend istream& operator>>(istream &in,Plural &a)
即把operator>>
的返回类型由istream
改为istream&
。只有这样,才能保证每一次调用operator>>
时,第一个参数in
为cin
本身,而非cin
的一个副本。
本篇文章为本人原创。转发请注明出处。
欢迎评论留言与我交流。
如果文章内容有疏漏,欢迎您在评论区指出。
感谢阅读,您的点赞和关注,是对我最大的鼓励和支持!