问题一
cannot bind non-const lvalue reference of type 'Complex&' to an rvalue of type 'Complex'
该错误提示出现的原因是,代码在进行函数调用或赋值等操作时,将一个临时对象(也称为右值)传递给了一个非常量左值引用类型的参数。对于这种情况,C++语言标准禁止这样的操作,因为非常量左值引用只能绑定到左值,而无法绑定到右值。
例如:
void setComplex(Complex& comp) {
// do something
}
int main() {
setComplex(Complex(1.0, 2.0)); // Error!
return 0;
}
这里在调用
setComplex
函数时,使用了一个右值Complex(1.0, 2.0)
作为实参,并试图将其绑定到一个非常量左值引用Complex& comp
上,从而导致了编译错误。解决这个问题的方法可以有两种:
- 将函数参数改为常量引用类型
const Complex& comp
,以使其可以接受右值参数。- 将实参转换成左值后再传递给函数参数。例如,可以将一个临时对象的值复制给一个命名变量,然后将该变量的引用传递给函数。
解决方式:
void setComplex(const Complex& comp) {
// do something
}
int main() {
Complex c(1.0, 2.0);
setComplex(c); // OK
setComplex(Complex(1.0, 2.0)); // OK
return 0;
}
问题二
运算符重载两个类cout与相加,而A+B不能直接用cout输出,还需要中间变量将A+B存下来再输出
#include<iostream>
using namespace std;
class Complex{
private:
double real;//实部
double image;//虚部
public:
//友元函数重载输入输出运算符
friend ostream& operator <<(ostream &os,Complex &com);
friend istream& operator>>(istream&is,Complex &com);
friend Complex &operator+(Complex &A,Complex &B);
friend Complex &operator-(Complex &A,Complex &B);
friend Complex &operator*(Complex &A,Complex &B);
friend Complex &operator/(Complex &A,Complex &B);
Complex(double a,double b){
real = a;
image = b;
}
Complex(){}
};
ostream& operator <<(ostream &os,Complex &com){
if(com.image>=0) os<<com.real<<"+"<<com.image<<"i"<<endl;
else os<<com.real<<com.image<<"i"<<endl;
return os;
}
istream& operator>>(istream&is,Complex &com){
return is>>com.real>>com.image;
}
Complex &operator+(Complex &A,Complex &B){
Complex C;
C.real = A.real+B.real;
C.image = A.image+B.image;
return C;
}
Complex &operator-(Complex &A,Complex &B){
Complex C;
C.real = A.real-B.real;
C.image = A.image-B.image;
return C;
}
Complex &operator*(Complex &A,Complex &B){
//ac-bd (ad+bc)i
Complex C;
C.real = A.real*B.real-A.image*B.image;
C.image = A.real*B.image+A.image*B.real;
return C;
}
Complex &operator/(Complex &A,Complex &B){
Complex C;
C.real = A.real*B.real+A.image*B.image/(B.image*B.image+B.real*B.real);
C.image = (A.image*B.real-A.real*B.image)/(B.image*B.image+B.real*B.real);
return C;
}
int main()
{
Complex A,B;
cin>>A>>B;
cout<<"A:"<<A<<endl;
cout<<"B:"<<B<<endl;
cout<<"A+B:"<<A+B<<endl;
cout<<"A-B:"<<A-B<<endl;
cout<<"A*B:"<<A*B<<endl;
cout<<"A/B:"<<A/B<<endl;
}
以上代码编译时会CE,原因是:
1.在实现operator+
函数时,返回了一个Complex
类型的引用,但是没有定义对应的构造函数。因此,在进行类似于A + B
这样的运算时,返回的对象类型并不是原先的Complex
类型,而是一组新的数据。当试图使用这些数据时可能会发生不可预料的错误。
此外,由于operator+
中返回的是一个临时创建的对象,该对象只能存活到表达式结束位置。所以如果直接将其作为参数传递给输出流,其所保存的信息在输出时可能已经不存在了,从而导致输出结果出错。
为了解决这个问题,应将operator+
函数的返回值类型改为Complex
类型(非引用类型),然后将计算的结果暂存到新的Complex
类型变量中再返回。
2.在operator<<
重载函数中,第二个参数应该是const类型的引用const Complex& com
。因为输出运算符不应该修改对象的状态。
在使用<<
操作符时,左操作数必须是一个输出流对象,但此处将Complex对象作为了左操作数。应该将输出流和Complex对象通过流插入操作符<<
连接起来,将其放在右侧,才能完成输出操作。比如可以像下面这样实现overload <<运算符的实现:
修正后的代码:
#include<iostream>
using namespace std;
class Complex{
private:
double real;//实部
double image;//虚部
public:
//友元函数重载输入输出运算符
friend ostream& operator<<(ostream &os,const Complex &com);
friend istream& operator>>(istream&is,Complex &com);
friend Complex operator+(Complex &A,Complex &B);
friend Complex operator-(Complex &A,Complex &B);
friend Complex operator*(Complex &A,Complex &B);
friend Complex operator/(Complex &A,Complex &B);
Complex(double a,double b){
real = a;
image = b;
}
Complex(){}
};
ostream& operator <<(ostream &os,const Complex &com){
if(com.image>=0) os<<com.real<<"+"<<com.image<<"i"<<endl;
else os<<com.real<<com.image<<"i"<<endl;
return os;
}
istream& operator>>(istream&is,Complex &com){
return is>>com.real>>com.image;
}
Complex operator+(Complex &A,Complex &B){
Complex C;
C.real = A.real+B.real;
C.image = A.image+B.image;
return C;
}
Complex operator-(Complex &A,Complex &B){
Complex C;
C.real = A.real-B.real;
C.image = A.image-B.image;
return C;
}
Complex operator*(Complex &A,Complex &B){
//ac-bd (ad+bc)i
Complex C;
C.real = A.real*B.real-A.image*B.image;
C.image = A.real*B.image+A.image*B.real;
return C;
}
Complex operator/(Complex &A,Complex &B){
Complex C;
C.real = A.real*B.real+A.image*B.image/(B.image*B.image+B.real*B.real);
C.image = (A.image*B.real-A.real*B.image)/(B.image*B.image+B.real*B.real);
return C;
}
int main()
{
Complex A,B;
cin>>A>>B;
cout<<"A:"<<A;
cout<<"B:"<<B;
cout<<"A+B:"<<A+B;
cout<<"A-B:"<<A-B;
cout<<"A*B:"<<A*B;
cout<<"A/B:"<<A/B;
}
运行结果
1 2
1 -2
A:1+2i
B:1-2i
A+B:2+0i
A-B:0+4i
A*B:5+0i
A/B:0.2+0.8i