代码之家  ›  专栏  ›  技术社区  ›  Hemant

在C语言中有没有办法在派生类中强制运算符重载?

  •  19
  • Hemant  · 技术社区  · 14 年前

    5 回复  |  直到 14 年前
        1
  •  26
  •   Codesleuth    14 年前

    您可以在基类中提供运算符重载,然后在其中一个类中调用一些已发布的抽象方法来完成该工作。

    public abstract class MyClass
    {
        public static MyClass operator +(MyClass c1, MyClass c2) 
        {
            return c1.__DoAddition(c2);
        }
    
        protected abstract MyClass __DoAddition(MyClass c2);
    }
    
        2
  •  9
  •   Marc Gravell    14 年前

    不,唯一明智的方法是让单元测试检查使用反射来找到所有具体的实现,然后验证这个条件。你可以的 哪一个

    另一种方法是删除操作符并使用基于接口的方法;例如,如果需要的话 T 拥有 +(T,T) 而不是运算符有一个与 Add(T) 方法。这里的另一个优点是,接口可以从泛型中使用(通常通过约束),而从泛型代码中使用操作符需要一些努力。

        3
  •  6
  •   abatishchev Marc Gravell    14 年前

    您可以在抽象基类中实现重载,但将实际操作细节委托给抽象方法。然后这将必须实现,并且重载将随着它们的实现而发生。

    public abstract class OverLoadingBase
    {
        public abstract OverLoadingBase DoAdd(OverLoadingBase y);
    
        public static OverLoadingBase operator +(OverLoadingBase x, OverLoadingBase y)
        {
            return x.DoAdd(y);
        }    
    }
    

    虽然我不确定这是否完整。

        4
  •  4
  •   Hubris    10 年前

    我以前也这么做过。。。

    public abstract class BaseClass<TClass> where TClass : BaseClass
    {
        public static TClass operator +(TClass c1, TClass c2) 
        {
            return c1.DoAddition(c2);
        }
    
        protected abstract TClass DoAddition(TClass c2);
    }
    

    然后实施如下:

    public class ConcreteClass : BaseClass<ConcreteClass>
    {
        protected ConcreteClass DoAddition(ConcreteClass c2)
        {
            ...
        }
    }
    
        5
  •  1
  •   Bear Monkey    14 年前

    因为它的操作符只能重载而不能重写,所以它的实现相当困难。我能想到的最好的解决方案是使用一个抽象类和这样的重载。

    public abstract class MyBase
    {
        public abstract MyBase Add(MyBase right);
        public abstract MyBase Subtract(MyBase right);
    
        public static MyBase operator +(MyBase x, MyBase y)
        {
            //validation here
            return x.Add(y);
        }
    
        public static MyBase operator -(MyBase x, MyBase y)
        {
            //validation here
            return x.Subtract(y);
        }
    }
    
        6
  •  0
  •   hdkrus    5 年前

    我会这样做:

    public abstract class Scalar<This> where This : Scalar<This>
    {
        public static This operator +(Scalar<This> a, This b) => a.Add(b);
    
        public abstract This Add(This another);
        ...
     }
    

    然后可以继承标量:

    public sealed class Rational : Scalar<Rational>
    {
        public override Rational Add(Rational another)
        {
          ...
        }
    
        ...
    }
    

    就这样:

    Rational a = ...;
    Rational b = ...;
    Rational sum = a + b;