首先看看运算符重载的基本语法。
要重载运算符,可以给类添加运算符类型成员(它们必须是static)。
我们先看一个简单的类:
public class AddClass1
{
public int val;
}
这仅是int值的一个包装器(wrapper),但可以用于说明规则。
对于这个类下面的代码不能编译:
AddClass1 op1 = new AddClass1();
op1.val = 5;
AddClass1 op2 = new AddClass1();
op2.val = 5;
AddClass1 op3 = op1 + op2;
其错误是+运算符不能应用于AddClass1类型的操作数,因为我们还没有定义要执行的操作。
虽然下面的代码可以执行,但是得不到我们希望的结果:
AddClass1 op1 = new AddClass1();
op1.val = 5;
AddClass1 op2 = new AddClass1();
op2.val = 5;
bool op3 = op1 == op2;
这仅是使用二元运算符==判断op1和op2是否引用的用一个对象,而不是验证他们的值是否相等。在这段代码中,即使op1.val和op2.val相等,op3也是false。因为它们引用的并不是同一个对象。
我们使用下面的方法来实现对+运算符的重载。
public class AddClass1
{
public int val;
public static AddClass1 operator +(AddClass1 op1, AddClass1 op2)
{
AddClass1 returnVal = new AddClass1();
returnVal.val = op1.val + op2.val;
return returnVal;
}
}
重载所有的二元运算符基本上都和这个相似。一元运算符看起来也是类似的,但是只有一个参数。
public static AddClass1 operator -(AddClass1 op1)
{
AddClass1 returnVal = new AddClass1();
returnVal.val = - op1.val;
return returnVal;
}
下面我们再看一个不同类的对象运算的例子。
public class AddClass1
{
public int val;
public static AddClass3 operator +(AddClass1 op1, AddClass2 op2)
{
AddClass3 returnVal = new AddClass3();
returnVal.val = op1.val + op2.val;
return returnVal;
}
}
public class AddClass2
{
public int val;
}
public class AddClass3
{
public int val;
}
对于这种类型的定义下面的代码也是可以执行的:
AddClass1 op1 = new AddClass1();
op1.val = 5;
AddClass2 op2 = new AddClass2();
op2.val = 5;
AddClass3 op3 = op1 + op2;
这是因为在AddClass1中定义的加运算符仅适合于AddClass1与AddClass2相加然后赋值给AddClass3对象。而且顺序必须是AddClass1对象在前,AddClass2对象在后的这种相加,如果要颠倒顺序,除非我们按照颠倒的顺序在进行一个运算符的重载,否则是不支持这种算法的。
下述运算符可以重载:
一元运算符:+, -, !, ~, ++, --, true, false
二元运算符:+, -, *, /, %, &, |, ^, <<, >>
比较运算符:==, !=, <, >, <=, >=
如果想重载==,必须还要重载!=