是否可以将重载提取运算符与重载算术运算符级联?

发布于 2024-10-16 04:45:37 字数 1248 浏览 4 评论 0原文

我正在尝试在 C++ 中实现一个类 COMPLEX 并重载算术运算符以及 '<<'和“>>”用于输入/输出的运算符。单独以及级联时,算术运算符按预期工作 - 但在尝试执行以下语句时我无法获得正确的结果:

cout &lt&lt "something" &lt&lt complex1 + complex2 &lt&lt "\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 &gt&gt (istream &, COMPLEX &);
    friend ostream& operator &lt&lt (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 &gt&gt (istream &i_s, COMPLEX &t_c){
    i_s &gt&gt t_c.a &gt&gt t_c.b;
    return i_s;
}

ostream& operator &lt&lt (ostream &o_s, COMPLEX &t_c){
    o_s &lt&lt t_c.a &lt&lt "+" &lt&lt t_c.b &lt&lt "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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你爱我像她 2024-10-23 04:45:37

问题是您的流插入运算符定义为

friend ostream& operator << (ostream &, COMPLEX &);

This 将对 COMPLEX 对象的非常量引用作为第二个参数。当您尝试编写

cout << a + b << endl;

The value of a + b is an rvalue,而不是 lvalue,因为它是函数 返回的值运算符+。在 C++ 中,您无法将引用绑定到右值,因为这样您可能会做这样的坏事:

COMPLEX& c = a + b; // This step isn't legal
c = 137;            // Wait, what object did we just change?

这里的问题是,如果我们可以将引用 c 绑定到 返回的临时对象a + b,然后我们可以使用引用来更改该对象。但这没有任何意义 - a + b 是表达式的值,而不是实际的对象。

这与这里发生的问题相同。您的 operator << 函数不能将 a + b 作为第二个参数,因为 a + b 是右值。

要解决此问题,您可以更改 operator << 来获取对 COMPLEX 的 const 引用:

friend ostream& operator<< (ostream& out, const COMPLEX& c);

这是有效的,因为在 C++ 中您可以将 const 引用绑定到右值。其背后的基本原理是,如果您有一个临时对象的 const 引用,则无法对该临时对象进行任何更改,因此上面绑定对 a + b 的引用的示例不再是一个问题。

一般来说,任何接受参数(其类型是类的另一个实例但不修改该实例)的重载运算符都应该通过 const 引用获取其参数。这适用于 operator =operator + 等,因为它避免了这个问题。

The problem is that your stream insertion operator is defined as

friend ostream& operator << (ostream &, COMPLEX &);

This takes a non-const reference to a COMPLEX object as the second parameter. When you try writing

cout << a + b << endl;

The value of a + b is an rvalue, not an lvalue, because it's the value returned by the function operator +. In C++, you cannot bind a reference to an rvalue, since then you could do Bad Things like this:

COMPLEX& c = a + b; // This step isn't legal
c = 137;            // Wait, what object did we just change?

The problem here is that if we can bind the reference c to the temporary object returned by a + 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 take a + b as a second parameter because a + b is an rvalue.

To fix this, you can change operator << to take const reference to a COMPLEX:

friend ostream& operator<< (ostream& out, const COMPLEX& c);

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.

不一样的天空 2024-10-23 04:45:37

您的运营商<<需要采用常量引用,否则,编译器将无法将 COMPLEX 类型的临时变量(由加法产生)转换为非常量引用,并且可能会寻找替代运算符 <<打电话。

friend ostream& operator << (ostream &, const COMPLEX &); //notice "const"

要了解其余的运算符机制,您只需查看运算符优先级表。

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.

friend ostream& operator << (ostream &, const COMPLEX &); //notice "const"

To understand the rest of the operator mechanics, you only need to take a look at the operator precedence table.

寒冷纷飞旳雪 2024-10-23 04:45:37

将您的 cout 语句重写为

cout << "something" << (complex1 + complex2) << "\n";

rewrite your cout statement to

cout << "something" << (complex1 + complex2) << "\n";
春花秋月 2024-10-23 04:45:37

你的问题是运算符<<总是在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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文