【问题标题】:How can I overload any arbitrary binary or unary operator for a class?如何为类重载任意二元或一元运算符?
【发布时间】:2017-10-07 21:47:13
【问题描述】:

假设你有一个类继承了一个数组x,添加了一些参数p

classdef test
    properties
       x
       p
    end
    methods
       function t=calculate(t)
           [t.x,t.p]=calc(x,p);
       end
       function t=plus(t1,t2)
           t.x=t1.x+t2.x;
       end
   end
end

已知如何重载二元运算符,例如plusmtimesminus 等。我怎样才能为 any 二元向量化运算符启用重载,或者最终,任何一元运算符,例如meanabsmax 等,以便直接应用于向量x?例如,我怎样才能让S = mean(S); 等同于S.x = mean(S.x);

【问题讨论】:

  • 也许这个类似的帖子可以帮助你:mathworks.com/matlabcentral/answers/…
  • 是的,我在写问题之前检查了这一点。使用类而不是 S0+S2-abs(S0) 为简单的算术运算编写 S0.oper(@plus,(S2.oper(@minus,(S0.oper(@abs))))) 或类似的东西仍然很奇怪.....
  • 你提到了“继承”。这是否意味着test 是包含x 的类的子类?如果是这样,该超类是否实现了任何内置运算符?
  • 如果x 是一个实现了内置运算符的类,或者x 是一个标准数组,我都会保留这个问题。我们可以放心地考虑最后一种情况。

标签: matlab class operator-overloading


【解决方案1】:

如果我正确理解您的问题,听起来您希望您的新类 test 简单地继承为属性 x 的类定义的所有二进制和一元方法(并在属性 x 上操作调用它们),这样您就不必自己重新定义它们。

如果这是您想要的,那么我认为唯一可行的方法是实际使用 inheritance 并使您的类 test 成为属性类的 subclass x。考虑到x 只是double 的简单情况,可以在here 中找到一个继承内置double 类型的好例子。将该示例改编为您的示例,这是您可以实现类test 的一种方法:

classdef test < double

  properties
    p
  end

  methods
    function obj = test(x, p)
      if (nargin < 2)
        p = 0;
        if (nargin < 1)
          x = 0;
        end
      end
      obj@double(x);
      obj.p = p;
    end

    function sref = subsref(obj, s)
      switch s(1).type
        case '.'
          switch s(1).subs
            case 'p'
              sref = obj.p;
            case 'x'
              x = double(obj);
              if (length(s) < 2)
                sref = x;
              elseif (length(s) > 1) && strcmp(s(2).type, '()')
                sref = subsref(x, s(2:end));
              end
            otherwise
              error('Not a supported indexing expression')
          end
        case '()'
          x = double(obj);
          newx = subsref(x, s(1:end));
          sref = test(newx, obj.p);
        case '{}'
          error('Not a supported indexing expression')
      end
    end

    function obj = subsasgn(obj, s, b)
      switch s(1).type
        case '.'
          switch s(1).subs
            case 'p'
              obj.p = b;
            case 'x'
              if (length(s) < 2)
                obj = test(b, obj.p);
              elseif (length(s) > 1) && strcmp(s(2).type, '()')
                x = double(obj);
                newx = subsasgn(x, s(2:end), b);
                obj = test(newx, obj.p);
              end
            otherwise
              error('Not a supported indexing expression')
          end
        case '()'
          x = double(obj);
          newx = subsasgn(x, s(1), b);
          obj = test(newx, obj.p);
        case '{}'
          error('Not a supported indexing expression')
      end
    end

    function disp(obj)
      fprintf('p:');
      disp(obj.p);
      fprintf('x:');
      disp(double(obj));
    end
  end

end

有一个警告:在 test 类的对象上使用 double 运算符和方法得到的结果将返回 double 类的结果,而不是你想要的 test。要获得您想要的行为,您必须每次将结果重新分配给属性 x,如下例所示:

>> a = test(1:3, pi)  % Create an object with p = pi, and x = [1 2 3]

a = 
p:   3.141592653589793
x:     1     2     3

>> a.x = -a  % Unary operation on a, and reassignment to x

a = 
p:   3.141592653589793
x:    -1    -2    -3

>> a.x = a+4  % Binary operation and reassignment

a = 
p:   3.141592653589793
x:     3     2     1

>> a.x = mean(a)  % Another unary operation and reassignment

a = 
p:   3.141592653589793
x:     2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    相关资源
    最近更新 更多