超载比较操作员

Overloading comparison operators

本文关键字:操作员 比较 超载      更新时间:2023-10-16

我在比较运算符><上遇到了麻烦。我尝试了两种不同的方法,但我仍然遇到麻烦。

bool Car::operator ==(const Car &car)
{
    return mLNumber == car.GetNum();
}
bool Car::operator <(const Car &carB)
{
    return mLNumber < carB.GetNum(); 
}
bool Car::operator >(const Car &carB)
{
    return mLNumber > carB.GetNum(); 
}
int Car::GetNum()
{
    return mLNumber;
}

我的==操作员工作正常。我发现这些操作员不存在的错误。这是我的第二次尝试。

bool Car::operator <(const Car &carA, const Car &carB)
{
    return carA.GetNum() < carB.GetNum(); 
}
bool Car::operator >(const Car &carB)
{
    return carA.GetNum() > carB.GetNum(); 
}

我发现有太多参数的错误。我也明白了:

'Car::GetNum' : cannot convert 'this' pointer from 'const Car' to 'Car &' 

尝试使操作员const

bool Car::operator <(const Car &carB) const {
    return mLNumber < carB.GetNum(); 
}
bool Car::operator >(const Car &carB) const {
    return mLNumber > carB.GetNum(); 
}

编辑:,在这种情况下,您也应该使GetNum()函数为const,因为您在const Car&对象上调用它。

您也不需要GetNum(),您可以写

bool Car::operator <(const Car &carB) const {
    return mLNumber < carB.mLNumber; 
}

代码中有两个问题 - first ,从逻辑上讲,您的操作员在类型上是不变的 - 他们不会更改对象,它们只能分析它们,您应该能够在不可变(const)对象上调用它们。因此,正如Alestanis指出的那样,使其const (所有操作员和Getter方法)。

第二< ==>是二进制操作员。有两个选择可以实现:作为免费运营商或成员。您和会员一起去了,这没关系,但是:

bool Car::operator <(const Car &carA, const Car &carB)

不声明二进制操作员。当您将操作员以成员的形式实现时,第一个参数隐含于当前对象(*this),因此应为

bool Car::operator <(const Car &carB) const

免费操作员看起来像:

bool operator < (const Car& carA, const Car& carB);

请注意,由于它不是成员,因此const没有意义。但是,请注意,第一个参数(carA)被标记为const,它对应于将const应用于成员版本中的方法(在引擎盖下,将this标记为const)。

这将有助于查看您在哪里称呼这些操作员。

您的第二个版本带有两个汽车参数,应该是全球运营商。因此,如果使用它们,则将汽车从定义中删除。

由于您在const汽车对象上的调用getnum,因此CAR :: getnum函数也需要为const。这样做的更肮脏的方法是抛弃构造,但这被皱眉了。

您的错误是要比较一个 const对象而操作员的错误并未标记为 const,作为一般规则,您应始终标记不将对象更改为对象的函数和操作员const这使生活更加轻松。例如:

bool Car::operator ==(const Car &car) const // <-- This function is const
{
    return mLNumber == car.GetNum();
}

问题是car::GetNum()未声明为const,因此您无法在carconst上调用它。操作员以const Car &carB为参数,因此您无法在carB上调用GetNum(),因为carBconst对象,但是GetNum()尚未声明为const

您应该养成声明所有不将对象修改为const的功能的习惯。要将函数声明为const,只需在闭合括号后附加const即可。在声明中以及定义中。例如:

class car {
    // ...
    void car::foo() const;
    // ...
};
void car::foo() const
{ /* ... */ }

或,如果您在类声明中定义了内联,

class car {
    // ...
    void car::foo() const
    { /* ... */ }
    // ...
};

尽管在这种特殊情况下并不是严格必要的(这意味着这不是为什么代码未编译),但由于相同的原因,操作员本身也应声明const(因此您也可以在const对象上使用它们。)

在第一种情况下:

您的操作员不会更改操作数的数据,然后应将其进行const:

bool Car::operator <(const Car &carB) const {
                                    //^^^^^
    return mLNumber < carB.GetNum(); 
}
bool Car::operator >(const Car &carB) const {
                                   // ^^^^^
    return mLNumber > carB.GetNum(); 
}
int Car::GetNum() const
                //^^^^^
{
    return mLNumber;
}

在第二种情况下,当操作员接受2个参数时,应将其实施为免费功能:

bool operator <(const Car &carA, const Car &carB)
{
    return carA.GetNum() < carB.GetNum(); 
}
bool operator >(const Car &carA, const Car &carB)
{
    return carA.GetNum() > carB.GetNum(); 
}