C++ 运算符重载未按预期工作

标签 c++ operator-overloading implicit-conversion

这是整个类(class)(复制/粘贴应该可以):

#include <cstdio>
#include <iostream>
using namespace std;

class Rational
{
    int _n = 0;
    int _d = 1;
public:
    Rational (int numerator = 0, int denominator = 1) : _n(numerator), _d(denominator) {};
    Rational (const Rational & rhs) : _n(rhs._n), _d(rhs._d) {};
    ~Rational();
    int numerator() const {
        return _n;
    };
    int denominator() const {
        return _d;
    };
    Rational & operator = (const Rational &);

};

Rational operator + (const Rational & lhs, const Rational & rhs)
{
    return ((lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator()), lhs.denominator() * rhs.denominator());
}

Rational::~Rational()
{
    _n = 0;
    _d = 1;
}

std::ostream & operator << (std::ostream & o, const Rational & r)
{
    if (r.denominator() == 1) {
        return o << r.numerator();
    } else {
        return o << r.numerator() << '/' << r.denominator();
    }
}


int main()
{
    Rational a = 7;
    cout << "a is: " << a << endl;

    Rational b(5,3);
    cout << "b is: " << b << endl;

    cout << a << " + " << b << " = " << a + b << endl;
    cout << 14 << " + " << b << " = " << 14 + b << endl << endl;

    return 0;
}

我想使用非成员运算符重载。代码可以编译,但显示错误的结果。最后两行应显示:

7 + 5/3 = 26/3

14 + 5/3 = 47/3

而是显示:

7 + 5/3 = 3

14 + 5/3 = 3

问题很可能是这样的:

Rational operator + (const Rational & lhs, const Rational & rhs)
{
    return ((lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator()), lhs.denominator() * rhs.denominator());
}

因为如果我将其更改为先创建对象然后返回,它就可以正常工作:

Rational operator + (const Rational & lhs, const Rational & rhs)
{
    Rational r((lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator()), lhs.denominator() * rhs.denominator());
    return r;
}

我期望隐式转换,并且两种解决方案都会给出相同的结果。 有人可以向我解释一下这里有什么区别吗?

最佳答案

return 语句包含逗号运算符调用,丢弃第一个表达式(应该是分子)的结果,并仅使用一个参数调用构造函数。您应该使用正确的初始化语法:

return Rational
(
    (lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator())
,   lhs.denominator() * rhs.denominator()
);

return
{
    (lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator())
,   lhs.denominator() * rhs.denominator()
};

或者(更好)

return Rational
{
    (lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator())
,   lhs.denominator() * rhs.denominator()
};

关于C++ 运算符重载未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54967952/

相关文章:

c++ - 将 C++ 比较器仿函数作为参数传递时出现问题

c++ - 反转字符串 C++

c++ - 在 C++ 中使用运算符重载添加复数

c++ - 转换构造函数的隐式参数

c++ - 添加从 unique_ptr<T> 到 T* 的隐式转换

c++ - DoModal() 没有将 dlg 框作为模态显示

c++ - 您能告诉我为什么出现此错误吗?它涉及到函数指针

c++ - 使用 `&&` 和 `const` 限定符重载 operator== 会导致 C++20 中的歧义

c++ - 使谷歌测试框架输出用户定义的类型

c# - 将泛型隐式转换为包装器