Реализуйте копию для классов Handle

Метод копирования для классов Handle

Копирование переменной handle приводит к появлению другой переменной handle, которая ссылается на тот же объект. Вы можете добавить функциональность копирования к классу Handle путем подкласса matlab.mixin.Copyable. Унаследованный copy метод позволяет вам делать неглубокие копии объектов класса. The CopyObj класс показывает поведение операций копирования.

classdef CopyObj < matlab.mixin.Copyable
   properties
      Prop
   end
end

Создайте объект CopyObj и присвойте указатель на класс line объект свойству Prop.

a = CopyObj;
a.Prop = line;

Скопируйте объект.

b = copy(a);

Подтвердите, что переменные указателя a и b обратитесь к различным объектам.

a == b
ans =

  logical

   0

Однако line объект, на который ссылаются a.Prop не был скопирован. Указатель, содержащийся в a.Prop относится к тому же объекту, что и указатель, содержащийся в b.Prop.

a.Prop == b.Prop
ans =

  logical

   1

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

Настройка операции копирования

Настройте указатель объекта копирования поведения путем вывода вашего класса из matlab.mixin.Copyable. The matlab.mixin.Copyable класс является абстрактным базовым классом, производным от класса handle. matlab.mixin.Copyable предоставляет шаблон для настройки операций копирования объектов путем определения:

  • copy - Запечатанный метод, который определяет интерфейс для копирования объектов

  • copyElement - Защищенный метод, который подклассы могут переопределить, чтобы настроить операции копирования объектов для подкласса

The matlab.mixin.Copyable copy метод, вызывает copyElement способ. Подкласс настраивает операцию копирования путем определения собственной версии copyElement.

Реализация по умолчанию copyElement делает неглубокие копии всех независимых свойств. copyElement копирует каждое значение свойства и присваивает его новому (скопированному) свойству. Если значение свойства является указателем объекта, copyElement копирует указатель, но не базовые данные.

Чтобы реализовать различное поведение копирования для различных свойств, переопределите copyElement. Для примера, copyElement метод SpecializedCopy класс:

  • Создает новый объект класса

  • Копирует значение Prop1 к новому объекту

  • Повторно инициализирует значение по умолчанию Prop2 путем добавления временной метки при создании копии

classdef SpecializedCopy < matlab.mixin.Copyable
   properties
      Prop1
      Prop2 = datestr(now)
   end
   methods(Access = protected)
      function cp = copyElement(obj)
         cp = SpecializedCopy;
         cp.Prop1 = obj.Prop1;
         cp.Prop2 = datestr(now);
      end
   end
end

Создайте объект класса и присвойте значение Prop1:

a  = SpecializedCopy;
a.Prop1 = 7
a = 

  SpecializedCopy with properties:

    Prop1: 7
    Prop2: '17-Feb-2015 17:51:23'

Используйте унаследованную copy метод для создания копии a:

b = copy(a)
b = 

  SpecializedCopy with properties:

    Prop1: 7
    Prop2: '17-Feb-2015 17:51:58'

Копия (объект b) имеет то же значение для Prop1, но подкласс copyElement метод присвоил новое значение Prop2. Заметьте другую временную метку.

Свойства копирования, содержащие указатели

Копирование объекта также копирует значения свойств объекта. Свойства объекта могут содержать другие объекты, включая указатель объекты. Если вы просто копируете значение свойства, которое содержит объект указатель, вы фактически копируете указатель, а не сам объект. Поэтому ваша копия ссылается на тот же объект, что и исходный объект. Классы, которые получают из matlab.mixin.Copyable класс может настроить, как метод копирования копирует объекты класса.

Класс, для которого поддерживается копирование указателей

Предположим, что вы задаете класс, который хранит указатель в свойстве объекта. Вы хотите иметь возможность копировать объекты класса и хотите, чтобы каждая копия объекта ссылалась на новый объект указателя. Настройте поведение копирования класса с помощью следующих шагов:

  • Создайте подкласс matlab.mixin.Copyable.

  • Переопределите copyElement для управления копированием свойства, содержащего указатель.

  • Поскольку значение свойства является указателем, создайте новый объект по умолчанию того же класса.

  • Скопируйте значения свойств из исходного объекта указателя в новый указатель объекта.

Класс HandleCopy настраивает операции копирования для свойства, содержащего объект указатель. Класс ColorProp задает указатель объекта, которую нужно назначить Prop2:

Создайте объект и присвойте значения свойств:

a = HandleCopy;
a.Prop1 = 7;
a.Prop2 = ColorProp;

Создайте копию объекта с помощью copy метод, унаследованный от matlab.mixin.Copyable:

b = copy(a);

Продемонстрировать, что объекты указателя, содержащиеся в объектах a и b являются независимыми. Изменение значения на объекте a не влияет на b объекта:

a.Prop2.Color = 'red';
b.Prop2.Color
ans =

blue

HandleCopy

The HandleCopy класс настраивает операцию копирования для объектов этого класса.

classdef HandleCopy < matlab.mixin.Copyable
   properties
      Prop1 % Shallow copy
      Prop2 % Handle copy
   end
   methods (Access = protected)
      function cp = copyElement(obj)
         % Shallow copy object
         cp = copyElement@matlab.mixin.Copyable(obj);
         % Get handle from Prop2
         hobj = obj.Prop2;
         % Create default object
         new_hobj = eval(class(hobj));
         % Add public property values from orig object
         HandleCopy.propValues(new_hobj,hobj);
         % Assign the new object to property
         cp.Prop2  = new_hobj;
      end
   end
   methods (Static)
      function propValues(newObj,orgObj)
         pl = properties(orgObj);
         for k = 1:length(pl)
            if isprop(newObj,pl{k})
               newObj.(pl{k}) = orgObj.(pl{k});
            end
         end
      end
   end
end

ColorProp

The ColorProp класс определяет цвет путем присвоения значения RGB его Color свойство.

classdef ColorProp < handle
   properties
      Color = 'blue';
   end
end

Исключить свойства из копии

Используйте NonCopyable атрибут свойства, указывающий, что операция копирования не должна копировать то или иное значение свойства. По умолчанию NonCopyable является false, что указывает, что значение свойства является копируемым. Можно задать NonCopyable на true только на свойствах классов handle.

Для классов, которые получают из matlab.mixin.Copyable, реализация по умолчанию copyElement чествует NonCopyable атрибут. Поэтому, если свойство имеет свою NonCopyable для атрибута задано значение true, затем copyElement не копирует значение этого свойства. Если вы переопределяете copyElement в подклассе можно выбрать, как использовать NonCopyable атрибут.

Установите для атрибута значение Not Copy

Задайте NonCopyable на true в блоке свойств:

properties (NonCopyable)
   Prop1
end

Значения по умолчанию

Если свойство, которое не копируется, имеет значение по умолчанию, назначенное в определении класса, операция копирования присваивает значение по умолчанию свойству. Для примера, CopiedClass присваивает значение по умолчанию Prop2.

classdef CopiedClass < matlab.mixin.Copyable
   properties (NonCopyable)
      Prop1
      Prop2 = datestr(now) % Assign current time
   end
end

Создайте копируемый объект и присвойте значение Prop1:

a = CopiedClass;
a.Prop1 = 7
a = 

  CopiedClass with properties:

    Prop1: 7
    Prop2: '17-Feb-2015 15:19:34'

Копировать a на b использование copy метод, унаследованный от matlab.mixin.Copyable:

b = copy(a)
b = 

  CopiedClass with properties:

    Prop1: []
    Prop2: '17-Feb-2015 15:19:34'

В b копирования, значение Prop1 не копируется. Значение Prop2 установлено значение по умолчанию MATLAB® определяется при первой загрузке класса. Временная метка не меняется.

Объекты с динамическими свойствами

Подклассы dynamicprops класс позволяет добавлять свойства к объекту класса. Когда класс выведен из dynamicprops также является подклассом matlab.mixin.Copyable, реализация по умолчанию copyElement не копирует динамические свойства. Значение по умолчанию NonCopyable является true для динамических свойств.

Реализация по умолчанию copyElement чтит значение динамического свойства NonCopyable атрибут. Если вы хотите разрешить копирование динамического свойства, задайте его NonCopyable атрибут к false. Копирование динамического свойства копирует значение свойства и значения атрибутов свойства.

Для примера эта операция копирования копирует динамическое свойство, DynoProp, потому что его NonCopyable для атрибута задано значение false. Объект obj должен быть образцом класса, который является производным от обоих dynamicprops и matlab.mixin.Copyable:

obj = MyDynamicClass;
p = addprop(obj,'DynoProp');
p.NonCopyable = false;
obj2 = copy(obj);

См. также

Похожие темы