Как работают свойства в объектно-ориентированном MATLAB? - PullRequest
25 голосов
/ 16 октября 2008

Я пытаюсь создать класс MATLAB с переменной-членом, которая обновляется в результате вызова метода, но когда я пытаюсь изменить свойство в классе, оно (по-видимому, из того, что я понял из управления памятью MATLAB) создает копию объекта и затем изменяет ее, оставляя свойство исходного объекта без изменений.

classdef testprop  
    properties  
        numRequests=0;  
    end  
    methods  
        function Request(this, val)  
            disp(val);  
            this.numRequests=this.numRequests+1;  
        end  
    end  
end  

.

>> a=testprop;
>> a.Request(9);
>> a.Request(5);  
>> a.numRequests  

ans = 0  

Ответы [ 3 ]

25 голосов
/ 16 октября 2008

Использование класса ванили

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

>> a=testprop
>> a.Request(5); % will NOT change the value of a.numRequests.
5

>> a.Request(5) 
5

>> a.numRequests
ans = 
       0

>> a=a.Request; % However, this will work but as you it makes a copy of variable, a.
5

>> a=a.Request; 
5

>> a.numRequests
ans =
       2

Использование класса дескриптора

Если вы наследуете от класса дескриптора, то это

classdef testprop < handle

тогда вы можете написать,

>> a.Request(5);
>> a.Request(5);
>> a.numRequests
ans = 
       2

Обновление: использование класса Vanilla

Поскольку Kamran отмечает, что вышеописанное работает, определение метода Request в коде примера вопроса необходимо изменить, чтобы включить выходной аргумент типа testprop .

Спасибо, Камран.

8 голосов
/ 10 ноября 2008

Вы должны помнить, что синтаксически в Matlab вы, вероятно, ближе к C, чем к C ++ или Java, по крайней мере, в отношении объектов. Итак, если вы хотите изменить «содержимое» объекта-значения (на самом деле это просто специальный struct), вам нужно вернуть объект из функции.

Azim был прав, когда указал, что если вы хотите поведение Singleton (что, как вам кажется, из вашего кода), вам нужно использовать класс handle. Экземпляры классов, производные от Handle, все указывают на один экземпляр и работают только с ним.

Вы можете узнать больше о различиях между классами Value и Handle.

4 голосов
/ 23 марта 2009

Я создал класс testprop и попытался извинить код, предложенный Azim, но он не работал Когда я выполнил следующую команду:

a=a.Request(1)

Произошла следующая ошибка:

??? Ошибка при использовании ==> Запрос Слишком много выходных аргументов.

Мне кажется, проблема в том, что мы не определили никакого вывода при объявлении метода Request Поэтому мы должны изменить его на:

function this = Request(this, val)

и сейчас:

>> a = testprop;
>> a = a.Request(1);        
>> a.numRequests

ans = 1
...