是否可以为执行算术运算的ostream运算符创建重载(例如,添加),然后流出结果?可以在整个Web上找到的标准ostream重载只能从单个变量中流式传输。我需要做以下事情:
std::cout << x+y << std::endl;
或甚至更复杂的表达式,如:
std::cout << x*y+(3*z)^2 << std::endl;
其中x,y和z是一个简单的定制结构的实例,其中已经定义了算术运算(重载)。
修改
这是我的代码:
struct scalar //complex scalar data structure
{
friend scalar operator^(const scalar&, int); //integer power operator overload
friend scalar exp(const scalar&); //exponential power function
std::ostream& operator<<(std::ostream&, const scalar&)
protected:
double re;
double im;
public:
double real() {return re;} //returns the real part
double imag() {return im;} //returns the imaginary part
scalar(double _re, double _im) {re=_re;im=_im;} //constructor 1
scalar(double _re) {re=_re;im=0.0;} //constructor 2
scalar(const scalar& s): re(s.re), im(s.im) {} //copy constructor
scalar& operator=(const scalar& rhs) //assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=rhs.re; //sets real parts equal
im=rhs.im; //sets imaginary parts equal
return *this;
}
scalar& operator+=(const scalar& rhs) //compound addition-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=re+rhs.re; //adds real parts
im=im+rhs.im; //adds imaginary parts
return *this;
}
scalar& operator*=(const scalar& rhs) //compound multiplication-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
double x1=re; double x2=rhs.re; double y1=im; double y2=rhs.im;
re=x1*x2-y1*y2; //multiplies real parts
im=x1*y2+x2*y1; //multiplies imaginary parts
return *this;
}
scalar& operator-=(const scalar& rhs) //compound subtraction-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=re-rhs.re; //adds real parts
im=im-rhs.im; //adds imaginary parts
return *this;
}
scalar& operator/=(const scalar& rhs) //compound division-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
double x1=re; double x2=rhs.re; double y1=im; double y2=rhs.im;
double n;
n =pow(x2,2)+pow(y2,2);
if (n==0) throw(1);
re=(x1*x2+y1*y2)/n; //multiplies real parts
im=(x2*y1-x1*y2)/n; //multiplies imaginary parts
return *this;
}
const scalar operator+(const scalar& b) //addition operator overload
{
scalar c = *this;
c+=b;
return c;
}
const scalar operator*(const scalar& b) //addition operator overload
{
scalar c = *this;
c*=b;
return c;
}
const scalar operator-(const scalar& b) //addition operator overload
{
scalar c = *this;
c-=b;
return c;
}
const scalar operator/(const scalar& b) //addition operator overload
{
scalar c = *this;
c/=b;
return c;
}
};
scalar i(0.0,1.0);
scalar j(0.0,1.0);
std::ostream& operator<<(std::ostream& out, const scalar& s)
{
out << s.re << '+' << s.im << 'i';
return out;
}
scalar operator^(scalar a, int b) //integer power operator overload
{
double x=a.real(); double y=a.imag();
if (x==0) throw(1);
int r=sqrt(pow(x,2)+pow(y,2));
int arg=atan2(y,x);
scalar c(r*cos(arg),r*sin(arg));
return c;
}
scalar exp(const scalar& s) //exponential power function
{
double x=s.re; double y=s.im;
scalar c(exp(x)*cos(y),exp(x)*sin(y));
return c;
}
这是我的主要功能:
int main()
{
scalar x(3,4);
scalar y=2;
cout << x*y << endl;
return 0;
}
这是它应该给出的输出:
6+8i
这就是它给出的错误:
In function 'std::ostream& operator<<(std::ostream&, const scalar&)':|
error: passing 'const scalar' as 'this' argument of 'double scalar::real()'
discards qualifiers|
如果我按照编译器的说法删除const
,我将收到以下错误:
error: no match for 'operator<<' in 'std::cout << scalar::operator*(const scalar&)
(((const scalar&)((const scalar*)(& y))))'|
答案 0 :(得分:3)
<<
运算符无法处理完整表达式 - 为什么要这样?
您需要为结构实现单独的运算符(operator +,operator *,...),它将结构作为参数,对其执行相应的操作,并返回另一个结构。只有然后定义一个operator<<
只接受你的一个结构。
你怎么会想到将这样一个复杂的结构传递给运算符&lt;&lt;,更不用说在那里解析了?实现单独的运算符,并将解析保留给编译器。
e.g。对于仅封装int
的简单结构,使用+
操作执行此操作将如下所示:
struct mystruct
{
int value;
};
然后定义:
mystruct const operator+(mystruct const & a, mystruct const & b)
{
mystruct result;
result.value = a.value + b.value;
return result;
}
和
std::ostream & operator<<(std::ostream& out, mystruct const & a)
{
out << a.value;
return out;
}
然后你可以这样做:
mystruct a, b;
a.value = 1;
b.value = 2;
std::cout << a+b;
修改:使用更新的代码,只有一个问题:
std::ostream& operator<<(std::ostream&, const scalar&)
应该是
friend std::ostream& operator<<(std::ostream&, const scalar&);
即。您遗漏了friend
和;
虽然您显示的错误表明存在一些不同的问题(jrok的答案会有解决方案) - 这似乎不是编译您显示的代码所致!因此,请同步显示所显示的代码和错误消息。
答案 1 :(得分:2)
你为什么不写std::cout << (x+y) << std::endl;
并完成?
答案 2 :(得分:2)
错误是因为函数scalar::real
和scalar::imag
不是const
- 当您获得对常量{const
的引用时,您只能调用scalar
成员函数1}}。
double real() const {return re;}
double imag() const {return im;}
答案 3 :(得分:1)
只要您的重载运算符按值获取其参数:
ostream& operator<<(ostream&, Thing)
或不断引用:
ostream& operator<<(ostream&, const Thing&)
您可以将其用于Thing
类型的任何表达式。
您应该在复杂表达式周围加上括号,以避免出现运算符优先级的意外情况;特别是,涉及^
的第二个表达式将不会按预期进行解析。
如果运算符需要非常量引用,则只限于单个变量(或更准确地说,左值表达式);所以不要这样做。
UPDATE 现在我们已经看到了代码,主要问题是operator<<
作为成员函数的类内定义;它不能成为会员。也许您希望它是friend
,因此它可以访问im
和re
;或者你应该删除声明(使其成为非成员,非朋友),并使用公共接口。如果您这样做,则需要将const
添加到real()
和imag()
,以便可以在const
对象上调用它们。无论如何你应该这样做。
(查看报告的错误,您似乎已经将其更改为使用公共接口,但尚未声明必要的函数const
)。