【问题标题】:The equality operator (==) in my class is not working我班上的相等运算符(==)不起作用
【发布时间】:2017-03-05 13:22:34
【问题描述】:

我一直在遵循一些 cpp 练习来学习 cpp,但遇到了问题。

我创建了一个名为“FixedPoint2”的类来实现一个定点数到小数点后两位。我已经包含了包含以下所有功能的头文件。

我正在苦苦挣扎的是,当我尝试测试相等运算符时,我总是得到错误的答案。换句话说,会发生以下情况:

cout << (FixedPoint2(1.0)==FixedPoint2(1.0)) << endl; //returns true as expected
cout << (FixedPoint2(1.2)==FixedPoint2(1.2)) << endl; //returns false
cout << FixedPoint2(1.2) << "\t" << FixedPoint2(1.2) << endl; returns 1.2 1.2 

所以你明白了。我还使用 if 语句对其进行了测试,以确保我的超载调用不是问题。例如:

if (FixedPoint2(4.5)==FixedPoint2(4.5)) 
    cout << "Don't post to stackoverflow"; //This doesn't print

我的直觉告诉我,要么是我忽略了一些隐式类型转换,要么是 double 中的一些混乱的东西。但我认为两者都不是。

using namespace std;


class FixedPoint2
{
    private:
        int16_t m_digi; //chosen because I want the range
        int8_t m_deci; //chosen to optimise memory 
    public:
        FixedPoint2(int16_t digi = 0, int8_t deci = 0):m_digi{digi}, m_deci{deci}
        {
            assert(!(deci>127 || deci<-127)); //to prevent overflows
            if(deci<-100 || deci>100) //just in case some moron (me) does some weird decimal calculations 
            {
                m_digi+=(static_cast<int16_t>(deci)/100);
                m_deci+=(-100);
            }
        }
    FixedPoint2(double mydouble) 
    {
        if (mydouble>=0) //The if-else floors the absolute value of the integer base
        {
            m_digi=static_cast<int16_t>(floor(mydouble));
        }
        else
        {
            m_digi=static_cast<int16_t>(floor(mydouble)+1);
        }
        m_deci=static_cast<int8_t>(round(100*(mydouble-m_digi))); //This rounds off the decimal to two digits

    };

    operator double();

    friend ostream& operator<<(ostream &out, const FixedPoint2 &f1);
    friend istream& operator>>(istream &in, FixedPoint2 &f1);
    friend FixedPoint2 operator+(const FixedPoint2 &f1, const FixedPoint2 &f2);
};

FixedPoint2::operator double()
{
    double base= static_cast<double>(m_digi);
    double decimal= static_cast<double>(m_deci);
    return base+0.01*decimal;
}

ostream& operator<<(ostream &out, const FixedPoint2 &f1)
{
    FixedPoint2 a=f1;
    out << double(a); //this is an easy work around to handling the period placement for the fixed point number
    return out;
}


istream& operator>>(istream &in, FixedPoint2 &f1)
{
    double placeholder;
    in>>placeholder;
    f1=FixedPoint2(placeholder);
    return in;
}

FixedPoint2 operator+(const FixedPoint2 &f1, const FixedPoint2 &f2)
{
    return FixedPoint2(f1.m_digi+f2.m_digi, f1.m_deci+f2.m_deci);
}

【问题讨论】:

  • 调试器是解决此类问题的正确工具。 询问 Stack Overflow 之前,您应该逐行浏览您的代码。如需更多帮助,请阅读How to debug small programs (by Eric Lippert)。至少,您应该 [编辑] 您的问题以包含一个重现您的问题的 Minimal, Complete, and Verifiable 示例,以及您在调试器中所做的观察。
  • operator== 的过载在哪里?
  • @c650 我认为他在 operator double(); 转换和比较双打方面已经过关了,这可能使其成为 Is floating point math broken? 的情况,但我们也没有定义 FixedPoint 所以我该怎么办知道吗?
  • 谢谢。下次我会遵守协议。根据我朋友的建议,我今天解决了这个问题。问题是 == 运算符没有被重载。我不知道为什么这会导致错误。有什么见解吗?
  • @A.Far C++ 中的类没有默认的operator==

标签: c++ class operator-overloading equality-operator


【解决方案1】:

编译器不会自动生成operator==,因为它出错的几率比正确的多得多。举个简单的例子:动态字符串。编译器会生成逐个字符比较的代码,对吧?它什么时候停止?现在编译器需要更多地了解程序员对他们的字符串的意图,并且编译器不需要心灵感应接口的额外复杂性。

最好有一致的规则,不,并强制明确定义要比较的内容,而不是因为人们假设他们得到了他们想要的东西而导致的垃圾代码雷区。在此处对该主题进行更长的讨论:Why don't C++ compilers define operator== and operator!=?

编译器四处寻找满足比较的方法。它没有找到直接的operator==,但它确实找到了operator doubledoubles 可用于比较。除了有时他们不能:Is floating point math broken?

也就是说我无法重现 OP 的结果。我希望在完全相同的输入上执行完全相同的公式以获得完全相同的结果,即使该结果是 1.199999... 而不是 1.2

虽然我无法重现,但 OP 最好还是实现定点 operator==,因为定点数没有不精确性。定点将相等或不相等,没有ifs ands or buts,所以“没有什么会出错!”另外,这个运算符写起来应该很简单。类似return (rhs.m_digi == lhs.m_digi) &amp;&amp; (rhs.m_deci == lhs.m_deci);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    相关资源
    最近更新 更多