为什么我的运算符重载处理左对象与右对象

Why does my operator overloading handle left versus right objects?

本文关键字:对象 处理 我的 运算符 重载 为什么      更新时间:2023-10-16

我有一个关于运算符重载的问题。下面是我的示例代码。如果你能通读一遍,我的问题就在下面。

//class definition
class example
{
private:
int a ; // Defined in FeetInches.cpp
public:
void seta(int f)
{
a = f;
}
example operator + (const example &); // Overloaded +
int geta()
{
return a;
}
};
example example::operator + (const example &right)
{
example temp;
temp.a = a + right.a;
return temp;
}

//主

#include "header" //this is the class definition above
#include <iostream>
using namespace std;
int main()
{
example r;
r.seta(1);
example s;
s.seta(1);
example t;
t = r + s;
t = r + 1;  //if included it won't compile
t = 1 + r; //if included it won't compile
int x = t.geta();
cout << x;
cin.get();
return 0;
}

我知道,当您试图使用运算符重载将对象添加到一起时,它们应该是相同的。

问题是:我最近看到,当对象位于它编译的运算符的一侧时,但当它位于另一侧时,它没有。例如:

它编译的CCD_ 1。t = 1 + r;没有。

(我也知道在我的例子中,这两种方法都不起作用,只是更容易用代码框出问题。)

当对象在运算符的一侧时,运算符重载是如何编译的,而当对象在另一侧时却不编译。

感谢

如果用语言重写有问题的语句,它看起来像:

t.operator=(1.operator+(r));

这没有多大意义,而且会混淆编译器。

由于混淆,它可以将数字1转换为example的实例,也可以将变量r转换为整数。不幸的是,你在课堂上也没有提供足够的信息。

如果你为你的类提供一个接受整数的构造函数,事情可能会变得不那么令人困惑:

class example
{
public:
example(int new_value) : a(new_value)
{ ; }
};

现在,您为编译器提供了一种将整数转换为examples的方法。

另一种选择是提供铸造或转换操作员:

class example
{
public:
int operator int (const example& e)
{
return e.a;
}
};

还有其他选择,例如创建一个接受整数的加法方法。

编辑1:
如果您正在设计单元类,请注意常数。你不知道常数是什么单位,比如英尺或英寸。编译器将无法提供帮助,因为数值常量没有关联的单位。

这真的很简单,当您重载运算符时,您可以通过两种方式来完成:

第一种方法是这样做的。你在其中插入了类的重载运算符。这样,左参数必须是这个类的对象。为什么?因为当您调用这个运算符时,您可以将其作为类中每个函数的调用。你不能用其他方式来做,因为你不能用其它类型来调用这个函数。

其次,您将重载运算符作为类的朋友。在你的课上,你写了这样一行:

friend example& operator + (const example &left, const example &right);

在你的类定义之后,你放了这个:

example& operator + (const example &left, const example &right){...}

所以,如果你想添加整数或其他类型,你必须修改你的运算符,这样添加:

example& operator + (const example &left, const int right){...}

或者这个:

example& operator + (const int left, const example &right){...}

如果要从运算器的左侧或右侧添加int,请选择一个或两个。

如果r定义了匹配的operator+()方法,则t = r + 1;表示t = r.operator+(1);,否则表示t = r + 1;0。它不编译,因为您没有定义任何+运算符,该运算符在左边取example,在右边取int,例如:
// as a class method:
class example
{
...
public:
...
example operator + (int right) const;
};
example example::operator + (int right) const
{
example temp;
temp.seta(a + right);
return temp;
}

或者:

// as a global operator:
class example
{
...
public:
...
friend example operator + (const example& left, int right);
};
example operator + (const example& left, int right)
{
example temp;
temp.seta(left.a + right);
return temp;
}

如果您定义了一个以int为输入的构造函数,那么当您将int值传递给example::operator+(const example&)方法时,编译器可能会创建一个临时example,例如:

class example
{
...
public:
example (int f);
...
example operator + (const example& right);
};
example::example::(int f)
: a(f)
{
}
example example::operator + (const example& right)
{
example temp;
temp.a = a + right.a;
return temp;
}

同样地,t = 1 + r;意味着t = operator+(1, r);(因为1不是类类型)。它不会编译,因为您没有定义一个全局+运算符,该运算符在左边取int,在右边取example

class example
{
...
public:
...
friend example operator + (int left, const example& right);
};
example operator + (int left, const example& right)
{
example temp;
temp.a = left + right.a;
return temp;
}