Реализация копии для Классов Handle

Копирование метода для Классов Handle

Копирование переменной указателя приводит к другой переменной указателя, которая относится к тому же объекту. Можно добавить функциональность копии к классу Handle путем разделения на подклассы matlab.mixin.Copyable. Наследованный метод copy позволяет вам сделать мелкие копии объектов класса. Класс 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

Для более подробной информации о поведении операции копии смотрите matlab.mixin.Copyable.copy копия.

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

Настройте поведение копии объекта указателя путем получения класса от matlab.mixin.Copyable. Класс matlab.mixin.Copyable является абстрактным базовым классом, который выводит от класса Handle. matlab.mixin.Copyable обеспечивает шаблон для настройки объектных операций копии путем определения:

  • matlab.mixin. Copyable.copy — Изолированный метод, который задает интерфейс для копирования объектов

  • matlab.mixin. Copyable.copyElement — Защищенный метод, который подклассы могут заменить, чтобы настроить объектные операции копии для подкласса

Метод copy matlab.mixin.Copyable, вызывает метод 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. Заметьте различную метку времени.

Copy Properties, которые содержат указатели

Копирование объекта также копирует значения свойств объектов. Свойства объектов могут содержать другие объекты, включая объекты указателя. Если вы просто копируете значение свойства, которое содержит объект указателя, вы на самом деле копируете указатель, не сам объект. Поэтому ваша копия ссылается на тот же объект как исходный объект. Классы, которые выводят от класса 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

Класс 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

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

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

Exclude Properties из копии

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

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

Установка атрибута не копировать

Установите NonCopyable на true в блоке свойства:

properties (NonCopyable)
   Prop1
end

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

Если свойству, которое не copyable, присвоили значение по умолчанию в определении класса, операция копии присваивает значение по умолчанию свойству. Например, 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);

Смотрите также

Похожие темы

Была ли эта тема полезной?