Matlab изменить значение атрибута методом - PullRequest
1 голос
/ 15 марта 2019

Я попытался изменить значение атрибута класса, вызвав одну из его функций-членов:

p1 = tank();
p1.checkOri(p1);

И в определении класса у меня есть статический метод:

classdef tank
    properties
        value
        ...
    end

    methods 
        ...

    methods (Static)
        function obj = checkOri(obj)
            if (CONDITION) %the thing I want it to do
                obj.value = EXPRESSION;
                ...

Все же этот checkOri метод не работает.Но если я напишу этот метод в основном файле или, скажем, изменив значение p1 - экземпляр класса tank - он будет работать отлично:

p1 = tank();
p1.checkOri(p1);
if (CONDITION) %the thing I want it to do
    p1.value = EXPRESSION;

Он работает отлично.

Интересно, что вызвало это.Исходя из моего опыта работы с другими языками программирования, вызов метода должен был сработать, это из-за некоторых трюков с синтаксисом Matlab или статическим методом?Как я мог это исправить, чтобы этот метод работал?

Ответы [ 2 ]

1 голос
/ 17 марта 2019

В MATLAB вызов

p1.checkOri();

эквивалентен

checkOri(p1);

В обоих случаях метод класса checkOri вызывается для класса объекта p1,передача p1 в качестве первого аргумента функции по значению .

Поскольку p1 передается по значению, любые изменения, внесенные в него внутри функции, не видны объектом ввызывая рабочее пространство.Поэтому обычно это делают

p1 = checkOri(p1);

Таким образом, объект, который был передан по значению и изменен внутри функции, передается обратно и присваивается переменной, в которой содержался исходный объект.

Если метод написан следующим образом:

function obj = checkOri(obj)
%...
end

, тогда MATLAB оптимизирует вызов функции выше, так что копия объекта фактически не создается.Обратите внимание, что как в объявлении функции, так и в вызове функции переменная ввода и вывода одинакова.

Как уже было обнаружено OP, вышеприведенное не относится к handle классам , классамкоторые наследуются от handle.Эти классы действуют так, как будто они всегда передаются по ссылке, и любые изменения, внесенные в них в любом рабочем пространстве, будут отражены во всех других копиях в других рабочих пространствах.

Присвоение переменной-члену также не следует приведенному выше,так что

p1.value = 0;

изменяет объект p1.

Для получения дополнительной информации о разнице между классами значений и классами дескрипторов см. этот другой вопрос .

1 голос
/ 17 марта 2019

Итак, как сказал @Navan в комментарии, класс дескриптора может быть решением.

Похоже, что у Matlab аналогичная концепция параметров с Java и C ++, аргументы, измененные в функции / методе, остаются только той модификацией внутри функции / метода.

Для этого класса я просто добавил < handle в заголовок определения класса, и это сработало:

classdef tank < handle
properties
    ...

Но я не уверен, что это единственное решение, возможно, есть лучшие способы сделать это. Так что я оставлю этот вопрос открытым, мы будем рады выслушать ваше мнение: D

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...