此代码对于重载比较运算符是否正确

Is this code correct for overloading comparision operator?

本文关键字:运算符 比较 是否 重载 代码 于重载      更新时间:2023-10-16

以下代码对于重载比较运算符是否正确?这段代码中是否有任何愚蠢的错误或漏洞?我特别怀疑 if 循环if (b1 == b2)if (&b1 == &b2)?哪一个是正确的,最终通过参考权,我想。如果我们在堆上分配对象,我们可以比较指针吗?

这是代码:

#include <QCoreApplication>
#include <iostream>
using namespace std;
class Base{
private:
    //static const int i=10;
    int j;
    string str;
public:
    //void display() const;
    //int read();
    bool operator==(const Base &rhs);
};
bool Base::operator ==(const Base &rhs)
{
    if((this->j == rhs.j) && (this->str == rhs.str))
        return true;
    else
        return false;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Base b1, b2;
    if(&b1 == &b2) // or if(b1 == b2)
    {
        cout << "Equaln";
    }
    else
    {
        cout << "Not equaln";
    }
    return a.exec();
}

这个函数签名告诉编译器,比较运算符可以更改对象值,因此不能在 const 对象上调用它。因此,最好将其声明为 const:

bool operator==(const Base &rhs) const;

在此代码中,您将比较两个对象的地址:

if(&b1 == &b2) // or if(b1 == b2)
{
    cout << "Equaln";
}
else
{
    cout << "Not equaln";
}

它们显然是不平等的。 如果 (b1 == b2) { ... } 如果要检查对象是否相等,请正确。

如果我们在堆上分配对象,我们可以比较指针吗?

如果 a 和 b 是指针,您可以将指针值比较为:

*a == *b 

或者显式调用运算符==(什么是丑陋的):

a->operator==(*b)

在 c++ 中,将此类运算符声明为好友是很常见的(但在您的情况下,这不是必需的)。此外,在此代码中使用它不会使可读性更好。我希望将此运算符视为:

bool Base::operator == (const Base & rhs) const
{
    return j == rsh.j and str == rhs.str;
}

作为一般说明,因为该类被称为 Base,您可能还需要将其声明为虚拟的。

补充:同样在这种情况下,j将不会初始化。修复它的最简单方法是将初始值设定项添加到声明中:

class Base {
private:
    int j = 0;
    string str;
// ...
};

比较运算符逻辑看起来是正确的,但是

  1. 您缺少const

    bool operator==(const Base &rhs) const;
    

    这是你对编译器的承诺,你的运算符不会修改调用它的实例;没有它,你的运算符就不能用于左侧const的比较。

  2. 当然它不是由行调用的

    if(&b1 == &b2) 
    

    因为这里您正在比较指针,指针已经具有它们的比较运算符(如果两个指针指向同一实例,则返回true)。实际调用运算符的正确方法是直接比较对象,例如

    if(b1 == b2)
    

发布的代码正在比较基本对象的内存地址。此 if 语句将始终比较 b1 和 b2 之间的 false,除非 b1 是 b2。

根据当前实现,进行以下更改将(&b1 == &b2)替换为(b1 == b2),您的代码就可以正常工作

(&b1 == &b2) => 比较地址,地址永远不会相同。 (b1 == b2) => 比较内容。