Генератор кода статически определяет время жизни объекта указатель. При использовании указателя объектов этот статический анализ имеет определенные ограничения.
При статическом анализе сгенерированный код может повторно использовать память, а не полагаться на динамическую схему управления памятью, такую как подсчет ссылок или набор мусора. Генератор кода может избежать динамического выделения памяти и автоматического управления памятью во время выполнения. Эти сгенерированные коды характеристики важны для некоторых критически важных приложений и приложений реального времени.
Ограничения см. в:
Генератор кода анализирует, заданы ли все переменные перед использованием. Неопределенные переменные или типы данных вызывают ошибку во время генерации кода. В определенных обстоятельствах генератор кода не может определить, заданы ли ссылки для обработки объектов. См. раздел Ссылки для обработки, Объекты могут появляться неопределенными.
Рассмотрим класс handle mycls
и функцию usehandle1
.
classdef mycls < handle properties prop end methods function obj = mycls(x) obj.prop = x; end end end
function y = usehandle1 p = mycls(0); % Instance of mycls with prop value 10 created for i = 1:10 p = mycls(i); % Handle object allocated inside loop end y = p.prop; % Handle object referenced outside loop end
Если вы пытаетесь сгенерировать код для usehandle1
функция, генератор кода производит ошибку. Ошибка возникает из-за:
Внутри указатель выделяется объекту for
цикл. Переменная p.prop
относится к этому указателю объекта.
Вне цикла переменная x относится к свойству
prop
объект указатель.
Если постоянная переменная ссылается на объект указатель, генератор кода допускает только один образец объекта во время жизни программы. Объект должен быть singleton объектом. Чтобы создать объект singleton указателя, заключайте операторы, которые создают объект в if isempty()
защитите постоянную переменную.
Например, рассмотрим класс mycls
и функцию usehandle2
. Генератор кода сообщает об ошибке для usehandle2
потому что p.prop
относится к mycls
объект, который оператор inner = mycls
создает. Этот оператор создает mycls
объект для каждого вызова usehandle2
.
classdef mycls < handle properties prop end end
function usehandle2(x) assert(isa(x, 'double')); persistent p; inner = mycls; inner.prop = x; if isempty(p) p = mycls; p.prop = inner; end
Если вы перемещаете операторы inner = mycls
и inner.prop = x
внутри if isempty()
охрана, генерация кода успешна. Оператор inner = mycls
выполняется только один раз в течение срока службы программы.
function usehandle2(x) assert(isa(x, 'double')); persistent p; if isempty(p) inner = mycls; inner.prop = x; p = mycls; p.prop = inner; end
Рассмотрим функцию usehandle3
. Генератор кода сообщает об ошибке для usehandle3
потому что постоянная переменная p
относится к mycls
объект, который оператор myobj = mycls
создает. Этот оператор создает mycls
объект для каждого вызова usehandle3
.
function usehandle3(x) assert(isa(x, 'double')); myobj = mycls; myobj.prop = x; doinit(myobj); disp(myobj.prop); function doinit(obj) persistent p; if isempty(p) p = obj; end
Если вы делаете myobj
сохраняет и заключает оператор myobj = mycls
внутри if isempty()
охрана, генерация кода успешна. Оператор myobj = mycls
выполняется только один раз в течение срока службы программы.
function usehandle3(x) assert(isa(x, 'double')); persistent myobj; if isempty(myobj) myobj = mycls; end doinit(myobj); function doinit(obj) persistent p; if isempty(p) p = obj; end
Рассмотрим функцию refHandle
который копирует свойство объекта указатель в другой объект. Функция использует простой класс handle и класс value. В MATLAB®функция запускается без ошибок.
function [out1, out2, out3] = refHandle() x = myHandleClass; y = x; v = myValueClass(); v.prop = x; x.prop = 42; out1 = x.prop; out2 = y.prop; out3 = v.prop.prop; end
classdef myHandleClass < handle properties prop end end
classdef myValueClass properties prop end end
Во время генерации кода возникает ошибка:
Property 'v.prop.prop' is undefined on some execution paths.
Три переменные ссылаются на то же место памяти: x
, y
, и v.prop
. Генератор кода определяет, что x.prop
и y.prop
иметь то же значение. Генератор кода не может определить, что свойство объекта handle v.prop.prop
разделяет его определение с x.prop
и y.prop
. Чтобы избежать ошибки, задайте v.prop.prop
непосредственно.