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

时间:2016-04-26 06:09:23

标签: c++ operator-overloading pass-by-reference

以下代码是否适用于重载比较运算符?这段代码中是否有任何愚蠢的错误或循环漏洞?我特别怀疑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 << "Equal\n";
    }
    else
    {
        cout << "Not equal\n";
    }
    return a.exec();
}

4 个答案:

答案 0 :(得分:4)

此函数签名对编译器说比较运算符可以更改对象值,因此无法在const对象上调用它。所以最好将它声明为const:

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

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

if(&b1 == &b2) // or if(b1 == b2)
{
    cout << "Equal\n";
}
else
{
    cout << "Not equal\n";
}

他们显然不平等。 if(b1 == b2){...}如果要检查对象是否相等则更正。

  

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

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

*a == *b 

或显式调用operator ==(丑陋):

a->operator==(*b)

在c ++中常见的是将这样的运算符声明为朋友(但在你的情况下,它不是必需的)。在此代码中使用此内容也不会使可读性更好。我想将此运算符视为:

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

总的来说,因为这个类叫做Base,所以你可能需要将它声明为虚拟。

ADDED:在这种情况下, j 也不会被初始化。修复它的最简单方法是将初始化程序添加到声明:

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

答案 1 :(得分:3)

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

  1. 您错过了const

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

    这是您对编译器的承诺,即您的运算符不会修改调用它的实例;没有它,您的操作员在左侧是const的比较中不可用。

  2. 当然不会被行

    调用
    if(&b1 == &b2) 
    

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

    if(b1 == b2)
    

答案 2 :(得分:1)

发布的代码是比较基础对象的内存地址。除非b1为b2,否则此if语句将始终在b1和b2之间进行比较。

答案 3 :(得分:1)

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

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