在MATLAB中模拟C ++模板

时间:2013-06-21 18:46:19

标签: matlab matlab-class

我试图找出创建C ++模板或Java通用对象的替代方法的最佳方法。我过去曾想过几次这样做,原因有几个,但是现在我想要做的就是为几个相关的类创建saveobj和loadobj函数。我的想法是,我希望有一组通用的例程来创建一个默认的结构,然后稍微操纵一下,以便按照我想要的方式获取结构。

我不能简单地使用外部函数,因为我需要访问对象的所有公共(非问题)和受保护(问题)非瞬态属性,以便创建loadobj和saveobj。

然后我考虑使用抽象接口。但是,使用抽象接口会给我带来同样的问题;相同,复制粘贴在我的所有目标文件中的代码。因此,我想到使用某种完整的对象结合多重继承(我的大多数对象已经从接口的基本具体结构继承)。我认为使用超类将允许我公开子类受保护的属性,但它似乎没有那样工作。有什么建议吗?

以下是save obj方法的多重继承方法(我目前最接近的)的一个示例。

Serializer.m

% Serializer.m
classdef Serializer 

  methods
    function [saveObj] = saveobj( obj )

      % Get metadata about the Object
      meta = metaclass( obj );
      meta = meta.PropertyList;

      for p = meta'
        if p.Transient | p.Dependent
          continue; % Only serialize the correct fields
        end

        saveobj.(p.Name) = { obj.(p.Name) }; % Serialize
      end % for ( property )
    end % function ( saveobj )
  end % methods
end % classdef ( Serializer )

TestSerializerA.m

% TestSerializerA.m
classdef TestSerializerA < Serializer
  properties
    PropA = 'a';
  end % properties ( public )

  properties( Access = protected )
    HiddenA = 'ha'
  end % properties ( protected )
end % classdef ( TestSerializerA )

TestSerializerB.m

% TestSerializerB.m
classdef TestSerializerB < TestSerializerA & Serializer

  properties
    PropB = 'b'
  end

  properties( Access = protected )
    HiddenB = 'hb';
  end % properties ( protected )

end % classdef ( TestSerializerB )  

1 个答案:

答案 0 :(得分:0)

解决方案

您可以使用Access lists完成您要执行的操作。您可以允许Serializer类访问您希望序列化的任何受保护/私有类成员。这允许每个类自己确定哪些成员被序列化。由于您允许访问Serializer,因此您不想继承它。如果你这样做,那么层次结构中的所有类都可以访问这些成员。这是重写的Serializer类:

classdef Serializer

    methods
        function SerializedObj = serialize(~, Obj)
            % Get metadata about the Object
            meta = metaclass(Obj);
            meta = meta.PropertyList;

            for p = meta' %'
                if p.Transient || p.Dependent
                    continue; % Only serialize the correct fields
                end
                try
                    SerializedObj.(p.Name) = { Obj.(p.Name) }; % Serialize
                catch Me
                    % the class has chosen not to allow this property to be
                    % serialized. decide how to handle it.
                    if ~strcmp(Me.identifier, 'MATLAB:class:GetProhibited')
                        Me.rethrow()
                    end
                end
            end
        end 

    end 

end

请注意,您可以决定如何处理访问限制。在上面的例子中,我什么都不做。但你可以发出警告,抛出错误等......

现在,不是继承自Serializer,而是创建一个抽象的Serializable类,它将启用序列化。

classdef (Abstract) Serializable

    properties (Access = private)
        Serializer_ = Serializer()
    end

    methods        
        function savedObj = saveobj(This)
            savedObj = This.Serializer_.serialize(This);
        end 

    end

end

现在,您希望启用序列化的任何类都将继承Serializable。您可以指定Serializer有权访问的受保护/私有成员。

实施例

以下类具有两个可序列化属性,以及一个隐藏(不可序列化)属性。

classdef TestSerializerA < Serializable
  properties
    PropA = 'a';
  end

  properties( Access = {?TestSerializerA, ?Serializer} )
      % This property is protected and serializable
      SerializableA = 'sa'
  end 

  properties (Access = private)
      % This property is private and not serializable
      HiddenA = 'ha';
  end
end

这是MATLAB的结果:

>> Test = TestSerializerA

Test = 

  TestSerializerA with properties:

    PropA: 'a'

>> b = saveobj(Test)

b = 

            PropA: {'a'}
    SerializableA: {'sa'}

下一个示例继承自TestSerializerA,并具有另外两个可序列化属性和一个隐藏属性。

classdef TestSerializerB < TestSerializerA & Serializable

    properties
        PropB = 'b';
    end

    properties (Access = {?TestSerializerB, ?Serializer})
        % This property is protected and serializable.
        SerializableB = 'sb';
    end

    properties (Access = protected)
        % This property is protected and not serializable.
        HiddenPropB = 'hb';
    end

end

请注意,从Serializable重新继承是不必要的,但更容易阅读代码。

最后,来自MATLAB的结果:

>> Test = TestSerializerB

Test = 

  TestSerializerB with properties:

    PropB: 'b'
    PropA: 'a'

>> b = saveobj(Test)

b = 

            PropB: {'b'}
    SerializableB: {'sb'}
            PropA: {'a'}
    SerializableA: {'sa'}

我希望这有帮助!