MATLAB - 运算符重载



MATLAB 中的运算符重载允许您为标准运算符(如 +、-、*、/ 等)定义自定义行为,当它们与您自定义类的对象一起使用时。当您希望类的对象以自然直观的方式相互交互或与其他 MATLAB 类型交互时,这尤其有用,类似于内置类型的行为。

为什么要重载运算符?

在 MATLAB 中重载运算符允许您为标准运算符(如 +、*、- 等)定义自定义行为,当它们与您的类对象一起使用时。这使得您可以以自然的方式使用您的对象,并与 MATLAB 的内置功能无缝集成。

例如:

  • 算术运算 - 如果您的类包含数值数据,您可以定义 + 或 * 等运算符如何与您的对象一起工作。这样,您可以直接对您的对象执行算术运算。
  • 关系运算 - 通过定义关系运算符(如 <、>、==),您可以在条件语句(如 if 或 switch)中使用您的对象。

简单来说,运算符重载使您的自定义对象的行为像内置 MATLAB 类型一样,允许您在代码中更直观地使用它们。

如何定义运算符?

在 MATLAB 中,您可以通过定义处理这些操作的方法来自定义标准运算符(如 +、-、* 等)如何与您的类对象一起工作。每个运算符都有一个相应的方法名称(例如,+ 运算符对应于 plus 方法)。要实现一个运算符,您需要在类中创建一个具有适当名称的方法,并定义操作步骤。

运算中的对象优先级

用户定义的类比内置类具有更高的优先级。这意味着如果您定义了您的类的一个对象并将其与内置类对象(如双精度浮点数)一起使用,如果存在,MATLAB 将使用您的类的方法。例如,如果 p 是您类的对象,而 q 是一个双精度浮点数,则 p + q 和 q + p 都将调用您类的 plus 方法。当来自不同用户定义类的对象一起使用时,MATLAB 将遵循优先级规则来决定调用哪个方法。

运算符优先级

MATLAB 根据预定义的操作顺序(称为优先级级别)计算表达式。这决定了表达式的哪些部分首先计算。同一级别的运算符从左到右计算。以下是从最高到最低优先级的顺序:

  • 括号: ()
  • 转置和幂: .', .^, .', ^
  • 一元运算: 一元减号、加号和逻辑非与幂: .^-, .^+, .^~
  • 一元运算: 一元加号、减号、逻辑非: +, -, ~
  • 乘法和除法: .*, ./, .\, *, /, \
  • 加法和减法: +, -
  • 冒号运算符: :
  • 关系运算符: <, <=, >, >=, ==, ~=
  • 按元素与: &
  • 按元素或: |
  • 短路与: &&
  • 短路或: ||

与和或运算符的优先级

MATLAB 赋予 & 运算符比 | 运算符更高的优先级。例如,表达式 a | b & c 将计算为 a | (b & c)。为了避免混淆,最好使用括号来清楚地指示预期的操作顺序。

覆盖默认优先级

您可以使用括号更改默认的计算顺序。例如:

A = [3 9 5];
B = [2 1 5];
C = A./B.^2 % Evaluates division after exponentiation
% C = [0.7500 9.0000 0.2000]

C = (A./B).^2 % Evaluates division before exponentiation
% C = [2.2500 81.0000 1.0000]

输出将是:

简而言之,定义运算符并理解它们的优先级允许您控制自定义对象如何与 MATLAB 的内置函数交互,并确保表达式按照您预期的顺序计算。

运算符重载示例

在 MATLAB 中,运算符重载允许您定义当与您的类的对象一起使用时特定运算符的行为。下面是一些带有解释的示例来说明这个概念。

示例 1:重载加号运算符

让我们创建一个简单的类来表示一个二维点,并重载 + 运算符以将两个点加在一起。

classdef Point
    properties
        X
        Y
    end
    methods
        function obj = Point(x, y)
            if nargin > 0
                obj.X = x;
                obj.Y = y;
            end
        end

        % Overload the plus operator
        function result = plus(obj1, obj2)
            result = Point(obj1.X + obj2.X, obj1.Y + obj2.Y);
        end
    end
end

将上述代码保存为 Point.m

在这个例子中,

  • 我们定义了一个 Point 类,具有 X 和 Y 属性。
  • 函数定义:function obj = Point(x, y) 定义了 Point 类的构造函数方法。构造函数是一个特殊的方法,在创建类的新的实例时会被调用。
  • 构造函数接受两个输入,x 和 y,它们用于初始化属性 X 和 Y。
  • if nargin > 0 条件检查构造函数是否带有任何参数被调用。nargin 是一个内置变量,它返回传递给函数的输入参数的数量。如果没有传递参数(即,nargin == 0),则属性 X 和 Y 不会被修改。
  • obj.X = x; 和 obj.Y = y; 将 x 和 y 的值赋值给新 Point 对象 (obj) 的属性 X 和 Y。
  • 函数 result = plus(obj1, obj2) 定义了一个方法来重载 Point 对象的 + 运算符。这意味着当您使用 + 运算符和两个 Point 对象时,将调用此方法。该方法接受两个输入,obj1 和 obj2,它们是 Point 类的实例。
  • result = Point(obj1.X + obj2.X, obj1.Y + obj2.Y); 创建一个新的 Point 对象 (result),其 X 和 Y 属性是 obj1 和 obj2 的 X 和 Y 属性的总和。它使用构造函数方法来使用相加的坐标创建这个新的 Point 对象。

让我们访问 Point 类并执行以下代码:

% Create two Point objects
p1 = Point(1, 2);
p2 = Point(3, 4);

% Use the overloaded + operator
p3 = p1 + p2;

% Display the result
disp(['X: ' num2str(p3.X) ', Y: ' num2str(p3.Y)]);

这里:

  • p1 = Point(1, 2); 创建一个 X=1,Y=2 的 Point 对象 p1。类似地,p2 = Point(3, 4); 创建另一个 X=3,Y=4 的 Point 对象 p2。
  • p3 = p1 + p2; 使用重载的 + 运算符将 p1 和 p2 相加,得到一个新的 Point 对象 p3,其中 X=4,Y=6。
  • p3 的坐标使用 disp 显示。

在 Matlab 命令窗口中执行后的输出为:

>> % Create two Point objects
p1 = Point(1, 2);
p2 = Point(3, 4);

% Use the overloaded + operator
p3 = p1 + p2;

% Display the result
disp(['X: ' num2str(p3.X) ', Y: ' num2str(p3.Y)]);

X: 4, Y: 6
>> 

示例 2:重载减号运算符

接下来,让我们重载 - 运算符,以便从一个点中减去另一个点。

classdef Point
    properties
        X
        Y
    end
    methods
        function obj = Point(x, y)
            if nargin > 0
                obj.X = x;
                obj.Y = y;
            end
        end

        % Overload the plus operator
        function result = plus(obj1, obj2)
            result = Point(obj1.X + obj2.X, obj1.Y + obj2.Y);
        end

        % Overload the minus operator
        function result = minus(obj1, obj2)
            result = Point(obj1.X - obj2.X, obj1.Y - obj2.Y);
        end
    end
end

将上述代码保存到 Point.m 文件中。现在,我们可以将 - 运算符与 Point 对象一起使用。

% Create two Point objects
p1 = Point(5, 7);
p2 = Point(2, 3);

% Use the overloaded - operator
p3 = p1 - p2;

% Display the result
disp(['X: ' num2str(p3.X) ', Y: ' num2str(p3.Y)]);

在 Matlab 命令窗口中执行后的输出为:

>> % Create two Point objects
p1 = Point(5, 7);
p2 = Point(2, 3);

% Use the overloaded - operator
p3 = p1 - p2;

% Display the result
disp(['X: ' num2str(p3.X) ', Y: ' num2str(p3.Y)]);

X: 3, Y: 4

示例 3:重载乘号运算符

最后,让我们重载 * 运算符,以便将一个点按标量值缩放。

if nargin > 0
   obj.X = x;
   obj.Y = y;
   end
     end

        % Overload the plus operator
        function result = plus(obj1, obj2)
            result = Point(obj1.X + obj2.X, obj1.Y + obj2.Y);
        end

        % Overload the minus operator
        function result = minus(obj1, obj2)
            result = Point(obj1.X - obj2.X, obj1.Y - obj2.Y);
        end

        % Overload the mtimes operator
        function result = mtimes(obj, scalar)
            result = Point(obj.X * scalar, obj.Y * scalar);
        end
    end
end

现在,我们可以使用 * 运算符来缩放 Point 对象。

% Create a Point object
p = Point(3, 4);

% Use the overloaded * operator to scale the point
p2 = p * 2;

% Display the result
disp(['X: ' num2str(p2.X) ', Y: ' num2str(p2.Y)]);

执行后的输出如下:

>> % Create a Point object
p = Point(3, 4);

% Use the overloaded * operator to scale the point
p2 = p * 2;

% Display the result
disp(['X: ' num2str(p2.X) ', Y: ' num2str(p2.Y)]);

X: 6, Y: 8
>>
广告