重载 +/- 一元运算符
Posted
技术标签:
【中文标题】重载 +/- 一元运算符【英文标题】:Overloading +/- unary operators 【发布时间】:2010-10-21 04:56:37 【问题描述】:当你重载 - 一元运算符时,对于不可变类型,你可以这样写:
public static Point3 operator - (Point3 p)
return new Point3 (-p.X, -p.Y, -p.Z);
但是对于+一元运算符,你应该如何实现呢?像这样:
public static Point3 operator + (Point3 p)
return p;
或者像这样:
public static Point3 operator + (Point3 p)
return new Point3 (p);
【问题讨论】:
在第二个例子中,你的意思是运算符+,而不是-? 是的,很抱歉错过了。 为了正确起见,'this' 不会存在于您的静态方法中。我认为您的意思是在重载中写“-p.X,-p.Y,-p.Z”。 【参考方案1】:嗯……
public static Point3 operator - (Point3 p)
return new Point3 (-p);
如果我错了,请纠正我,但这不是设置了无限递归吗?您在一元 (-) 运算符方法中调用一元 (-) 运算符。
在我看来你会想要这样做:
public static Point3 operator - (Point3 p)
return new Point3 (-(p.X), -(p.Y), -(p.Z));
// EDIT: Added parens for the sake of explicity. I don't recall the operator precedence in this case.
假设您的 Point3 类上有这样的构造函数和属性。
【讨论】:
谢谢,是的,我没注意这个,我猜是卡住了。【参考方案2】:在我看来,这取决于 Point3.Equals() 的实现。
考虑以下代码:
Dictionary<Point3, string> cache;
Point3 pointA = new Point3(1, 2, 3);
Point3 pointB = new Point3(1, 2, 3);
cached[pointA] = "Value Aaa";
cached[pointB] = "Value Bbb";
Console.WriteLine(cached[pointA]);
Console.WriteLine(cached[pointB]);
如果 Point3 有引用语义(pointA.Equals(pointB) 当它们是同一个对象时),这将输出:
Value Aaa
Value Bbb
如果 Point3 具有值语义(当它们的 x、y 和 z 值相等时,pointA.Equals(pointB)), 这将输出:
Value Bbb
Value Bbb
对于值语义,是否创建新对象并不重要。您可能只是返回相同的内容以避免产生垃圾。
如果您的类型具有引用语义,您可能希望一元加号创建一个新对象,以便它的行为方式与其他运算符相同。
【讨论】:
【参考方案3】:无论哪种方式都可以。您不会在这两种方法中的任何一种中改变原始对象。
如果你调用string.substring(0, string.length())
,没有理由不能返回原始字符串。
您签署的唯一具有不变性的合同是,一旦创建了对象,它就不会改变。
【讨论】:
【参考方案4】:我无法想象它会对不可变类型产生影响。最好只返回p
,principle of least surprise。
【讨论】:
【参考方案5】:如果结构是不可变的,你可以选择,我会返回原始值。
如果可变,则返回一个新的。
【讨论】:
【参考方案6】:我更喜欢第二种方法(虽然它会更慢),但假设 Point3
是一个 3D 点,它可能应该是 struct
而不是 class
。
【讨论】:
以上是关于重载 +/- 一元运算符的主要内容,如果未能解决你的问题,请参考以下文章