是否可以将重载提取运算符与重载算术运算符级联?
我正在尝试在 C++ 中实现一个类 COMPLEX 并重载算术运算符以及 '<<'和“>>”用于输入/输出的运算符。单独以及级联时,算术运算符按预期工作 - 但在尝试执行以下语句时我无法获得正确的结果:
cout << "something" << complex1 + complex2 << "\n";
其中complex1和complex2是COMPLEX类的对象。
类定义的片段:
class COMPLEX{
int a; // Real part
int b; // Imaginary part
public:
COMPLEX operator = (COMPLEX );
COMPLEX operator + (COMPLEX ) const;
friend istream& operator >> (istream &, COMPLEX &);
friend ostream& operator << (ostream &, COMPLEX &);
-snip-
}
COMPLEX COMPLEX::operator = (COMPLEX t_c) {
return COMPLEX(a = t_c.a, b = t_c.b);
}
COMPLEX COMPLEX::operator + (COMPLEX t_c) const{
return COMPLEX(a + t_c.a, b + t_c.b);
}
istream& operator >> (istream &i_s, COMPLEX &t_c){
i_s >> t_c.a >> t_c.b;
return i_s;
}
ostream& operator << (ostream &o_s, COMPLEX &t_c){
o_s << t_c.a << "+" << t_c.b << "i";
return o_s;
}
除此之外,我还重载了运算符。
每当我尝试级联<<时对于任何其他重载运算符,重载 <<友元函数没有被调用。相反,操作员被呼叫并显示结果。
I am trying to implement a class COMPLEX in C++ and overload the arithmetic operators as well as the '<<' and '>>' operators for input/output. Individually and also when cascaded the arithmetic operators work as expected - but i am unable to obtain correct results when trying to execute statements such as:
cout << "something" << complex1 + complex2 << "\n";
where complex1 and complex2 are objects of the class COMPLEX.
snippets of class definition:
class COMPLEX{
int a; // Real part
int b; // Imaginary part
public:
COMPLEX operator = (COMPLEX );
COMPLEX operator + (COMPLEX ) const;
friend istream& operator >> (istream &, COMPLEX &);
friend ostream& operator << (ostream &, COMPLEX &);
-snip-
}
COMPLEX COMPLEX::operator = (COMPLEX t_c) {
return COMPLEX(a = t_c.a, b = t_c.b);
}
COMPLEX COMPLEX::operator + (COMPLEX t_c) const{
return COMPLEX(a + t_c.a, b + t_c.b);
}
istream& operator >> (istream &i_s, COMPLEX &t_c){
i_s >> t_c.a >> t_c.b;
return i_s;
}
ostream& operator << (ostream &o_s, COMPLEX &t_c){
o_s << t_c.a << "+" << t_c.b << "i";
return o_s;
}
apart from this i have also overloaded operator.
When ever i try to cascade << with any other overloaded operator, the overloaded << friend function is not getting called. Instead the operator is getting called and the result of that is being displayed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是您的流插入运算符定义为
This 将对
COMPLEX
对象的非常量引用作为第二个参数。当您尝试编写The value of
a + b
is an rvalue,而不是 lvalue,因为它是函数返回的值运算符+
。在 C++ 中,您无法将引用绑定到右值,因为这样您可能会做这样的坏事:这里的问题是,如果我们可以将引用
c
绑定到返回的临时对象a + b
,然后我们可以使用引用来更改该对象。但这没有任何意义 -a + b
是表达式的值,而不是实际的对象。这与这里发生的问题相同。您的
operator <<
函数不能将a + b
作为第二个参数,因为a + b
是右值。要解决此问题,您可以更改
operator <<
来获取对 COMPLEX 的const
引用:这是有效的,因为在 C++ 中您可以将 const 引用绑定到右值。其背后的基本原理是,如果您有一个临时对象的 const 引用,则无法对该临时对象进行任何更改,因此上面绑定对
a + b
的引用的示例不再是一个问题。一般来说,任何接受参数(其类型是类的另一个实例但不修改该实例)的重载运算符都应该通过 const 引用获取其参数。这适用于
operator =
、operator +
等,因为它避免了这个问题。The problem is that your stream insertion operator is defined as
This takes a non-const reference to a
COMPLEX
object as the second parameter. When you try writingThe value of
a + b
is an rvalue, not an lvalue, because it's the value returned by the functionoperator +
. In C++, you cannot bind a reference to an rvalue, since then you could do Bad Things like this:The problem here is that if we can bind the reference
c
to the temporary object returned bya + b
, then we could use the reference to make changes to that object. But this doesn't make any sense -a + b
is the value of an expression, not an actual object.This is the same problem that's going on here. Your
operator <<
function can't takea + b
as a second parameter becausea + b
is an rvalue.To fix this, you can change
operator <<
to takeconst
reference to a COMPLEX:This works because in C++ you can bind const references to rvalues. The rationale behind this is that if you have a const reference to a temporary, you can't make any changes to that temporary object, so the above example with binding a reference to
a + b
is no longer a problem.In general, any overloaded operator that takes in a parameter whose type is another instance of the class that doesn't modify that instance should take its parameter by const reference. This goes for things like
operator =
,operator +
, etc. because it avoids this problem.您的运营商<<需要采用常量引用,否则,编译器将无法将 COMPLEX 类型的临时变量(由加法产生)转换为非常量引用,并且可能会寻找替代运算符 <<打电话。
要了解其余的运算符机制,您只需查看运算符优先级表。
Your operator << needs to take a constant reference, otherwise, the compiler will not be able to cast a temporary of type COMPLEX (which results from the addition) into a non-const reference, and might look for an alternative operator << to call.
To understand the rest of the operator mechanics, you only need to take a look at the operator precedence table.
将您的
cout
语句重写为rewrite your
cout
statement to你的问题是运算符<<总是在operator+之前调用。您提供重载的事实不会改变这一点。
另一方面,您通常不应该将计算与 I/O 混合在一起(也许只是为了节省一些输入),因为这使得很难看到计算的顺序。
Your problem is that operator<< is always called before operator+. The fact that you provide overloads doesn't change this.
On the other hand, you generally shouldn't mix computations an I/O anyway (perhaps only to save some typing), because that makes it hard to see the order of your computations.