我正在尝试在 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;
}
除此之外,我还重载了运算符。
当我尝试将 << 与任何其他重载运算符级联时,重载的 << 友元函数不会被调用。取而代之的是调用运算符(operator)并显示其结果。
最佳答案
问题是你的流插入运算符定义为
friend ostream& operator << (ostream &, COMPLEX &);
这需要对 COMPLEX
的非常量引用对象作为第二个参数。当你尝试写作时
cout << a + b << endl;
a + b
的值是右值,而不是左值,因为它是函数operator +
返回的值.在 C++ 中,您不能将引用绑定(bind)到右值,因为那时您可以做这样的坏事:
COMPLEX& c = a + b; // This step isn't legal
c = 137; // Wait, what object did we just change?
这里的问题是,如果我们可以绑定(bind)引用 c
a + b
返回的临时对象,然后我们可以使用引用对该对象进行更改。但这没有任何意义 - a + b
是表达式的值,而不是实际对象。
这与此处发生的问题相同。你的operator <<
函数不能带a + b
作为第二个参数,因为 a + b
是右值。
要解决此问题,您可以更改 operator <<
采取const
引用复杂的:
friend ostream& operator<< (ostream& out, const COMPLEX& c);
这是可行的,因为在 C++ 中,您可以将 const 引用绑定(bind)到右值。这背后的基本原理是,如果您有一个对临时对象的 const 引用,则不能对该临时对象进行任何更改,因此上面的示例绑定(bind)了对 a + b
的引用。不再是问题。
一般来说,任何接受参数的重载运算符,其类型是不修改该实例的类的另一个实例,都应该通过 const 引用获取其参数。这适用于 operator =
之类的事情, operator +
等,因为它避免了这个问题。
关于c++ - 是否可以将重载的提取运算符与重载的算术运算符级联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4909399/