C++布尔运算符==

C++ Bool Operator==

本文关键字:运算符 布尔 C++      更新时间:2023-10-16

我只是尝试创建一个比较 2 个对象的函数,但它给了我:

错误:bool Duree::operator==(const Duree&, const Duree&)必须只接受一个参数

我该如何解决这个问题?谢谢。

杜里·

#ifndef DEF_DUREE
#define DEF_DUREE
class Duree
{
public:
    Duree(int heures = 0, int minutes = 0, int secondes = 0);
    bool estEgal(Duree const& b) const;
    bool operator==(Duree const& a, Duree const& b);
private:
    int m_heures;
    int m_minutes;
    int m_secondes;
};
#endif

杜里.cpp

#include "Duree.h"
Duree::Duree(int heures, int minutes, int secondes) : m_heures(heures), m_minutes(minutes), m_secondes(secondes)
{
}
bool Duree::estEgal(Duree const& b) const
{
    return (m_heures == b.m_heures && m_minutes == b.m_minutes && m_secondes == b.m_secondes);
}
bool operator==(Duree const& a, Duree const& b)
{
    return a.estEgal(b);
}

主.cpp

#include <iostream>
#include "Duree.h"
using namespace std;
int main()
{
    Duree fisrt(10, 10, 10), second(15, 20);
    if (fisrt == second)
        cout << "Les durees sont identiques";
    else
        cout << "Les durees sont differentes";
    return 0;
}

要么用两个参数将operator==声明为自由函数:

bool operator==(Duree const& a, Duree const& b);

或作为只有一个参数的成员函数:

bool Duree::operator==(Duree const& b);

这是因为当您执行x == y时,您只比较两个对象。如果你有一个成员函数,那么会传递一个隐式的"this对象"(你调用operator==的对象(,使其成为 3 个参数而不是 2 个参数。

话虽如此,从您编写代码的方式来看,我猜您只是忘记在类定义中的operator==声明前面放置friend

可能有用的提示:您可以在支持它的编译器(基本上每个"主"编译器(上使用#pragma once,而不是包含保护。 :)

将原型更改为bool operator==(Duree const& rhs);或使其成为类Duree之外的免费函数。

总是喜欢二进制函数是非成员(自由(函数。 否则,如果使用不同类型的运算符重载,则可能会遇到问题。 请考虑以下人为的代码:

struct Foo {
   int x;
   bool operator==(Foo const & other) const { return x == other.x; }
};

这应该可以很好地将两个 Foos 进行比较。 但它有一个问题。 假设您还想与 int 进行比较:

struct Foo {
   int x;
   bool operator==(Foo const & other) const { return x == other.x; }
   bool operator==(int other) const { return x == other; }
};

现在,您可以比较一种方式,但不能比较另一种方式:

Foo a, b;
...
a == b; // ok
a == 123; // ok
123 == a; // ERROR

作为成员函数,对象必须位于右侧。

很简单,将 int-Foo 重载移出类,并制作两个版本,Foo==int 和 int==Foo? (注意,让他们在课堂上声明为朋友也可以做到这一点,FWIW,但我不在这里展示。

struct Foo {
   int x;
   bool operator==(Foo const & other) const { return x == other.x; }
};
bool operator==(int other, Foo const& f) { return f.x == other; }
bool operator==(Foo const& f, int other) { return f.x == other; }

所以现在一切正常,对吧? 我们有会员和非会员运营商的混合体。

a == b; // ok
a == 123; // ok
123 == a; // ok

直到 Foo 开始获取想要使用运算符的成员函数......

struct Foo {
   int x;
   bool operator==(Foo const & other) const { return x == other.x; }
   void g(int x);
};
bool operator==(int other, Foo const& f) { return f.x == other; }
bool operator==(Foo const& f, int other) { return f.x == other; }
void Foo::g(int x)
{
    Foo f = getOtherFoo();
    if (f == x) { // ERROR!  cannot find operator==(Foo,int)
      //...
    }
}

它仍然有问题! 在Foo的成员内部,它看不到非成员操作员,因为成员隐藏他们! g(( 不会编译,因为它无法将 Foo 与 int 进行比较。 移出所有运算符将解决它,因为那时所有重载都在同一范围内。

(请记住,名称查找会一直搜索外部作用域,直到找到要查找的名称的第一大小写,然后只考虑在该作用域中找到的所有名称。 在 g(( 中,它的作用域在类中,并且由于它在类中找到了一个版本的运算符(错误的运算符(,因此它永远不会在类外查找更多重载。 但是,如果他们都在课堂之外,它会同时找到他们。

struct Foo {
   int x;
   void g(int x);
};
// NON MEMBER
bool operator==(Foo const & lhs, Foo const & rhs) { return lhsx == rhs.x; }
bool operator==(int other, Foo const& f) { return f.x == other; }
bool operator==(Foo const& f, int other) { return f.x == other; }
void Foo::g(int x)
{
    Foo f = getOtherFoo();
    if (f == x) { // OK now, finds proper overload
      //...
    }
}

现在,它可以在所有情况下进行编译。 这就是为什么他们说,"总是喜欢让非成员二进制运算符重载。 否则,您最终可能会出现对称性和隐藏问题。

我遇到了同样的问题。通过将带有两个参数的operator==放回 main 中.cpp在main() ;)之前

工作