我只是尝试制作一个比较2个对象的函数,但它给了我:
错误:
bool Duree::operator==(const Duree&, const Duree&)
必须只接受一个参数
我该如何解决这个问题?谢谢。
Duree.h
#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
Duree.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);
}
Main.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;
}
答案 0 :(得分:9)
要么将operator==
声明为具有两个参数的自由函数:
bool operator==(Duree const& a, Duree const& b);
或作为只有一个参数的成员函数:
bool Duree::operator==(Duree const& b);
这是因为当您执行x == y
时,您只比较两个对象。如果你有一个成员函数,那么会传递一个隐含的“this
对象”(你称之为operator==
的对象),使其成为3个参数而不是2个。
话虽如此,从编写代码的方式来看,我猜你只是忘了在类定义中将friend
放在operator==
声明的前面。
可能有用的提示:您可以在支持它的编译器(基本上每个“主”编译器)上使用#pragma once
,而不是包含保护。 :)
答案 1 :(得分:2)
将原型更改为bool operator==(Duree const& rhs);
或将其设为课程Duree
以外的免费功能。
答案 2 :(得分:0)
始终优先选择二进制函数为非成员(免费)函数。否则,如果使用不同类型重载运算符,则可能会遇到问题。请考虑以下设计代码:
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()内部,它的范围在class,因为它在类中找到了一个运算符的版本(错误的一个),它从不在类外面寻找更多的重载。但是如果它们都在类之外,它将同时找到它们。 )
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
//...
}
}
现在,它汇编了所有案例。这就是为什么他们说,“总是喜欢让非成员二元运算符重载。”否则你最终会出现对称性和隐藏问题。
答案 3 :(得分:-2)
我遇到同样的问题。
通过在operator==
;之前将main()
两个参数放回main.cpp中来工作