【问题标题】:How to assign pointers to an object's property in MATLAB?如何在 MATLAB 中为对象的属性分配指针?
【发布时间】:2016-02-06 05:58:48
【问题描述】:

我想创建一个有限元面向对象的程序。我有一个类 Node。由于有限元网格中的节点(由 Mesh 类表示)是不同的,因此我创建了 Node 类作为值类。当我从类 Node 实例化对象数组时,我将该对象数组分配给 Mesh 的节点属性。我也有一个 Element 类,代表一个有限元。我还从这个类创建了一个对象数组并将其分配给 Mesh 的元素属性。到现在都清楚了。

由于有限元节点也属于元素,我想将一些节点分配给适当的元素。但是复制节点会导致数据冗余,因此我想将指针分配给 Node 对象,以便 ElementlocalNodes 属性包含一个数组指向特定节点的指针。我应该如何修改下面的类来实现它?

节点类:

classdef Node

   properties
      coordinate;
   end

   methods
     % Not interesting for this example
   end

end

元素类:

classdef Element

   properties
      localNodes; % the object instantiated from the class Element
                  % will store an array of pointers to the
                  % appropriate elements of the object array stored
                  % in Mesh.nodes. How can I assign these pointers
                  % to Element.localNodes?
   end

   methods
     % Not interesting for this example
   end

end

Mesh类:

classdef Mesh

   properties
      nodes;    % its object will contain an object array of Node
      elements; % its object will contain an object array of Element
   end

   methods
     % Not interesting for this example
   end

end

【问题讨论】:

    标签: matlab oop pointers


    【解决方案1】:

    最后,在这里进行一些讨论是我将如何解决这个问题的起点:

    classdef Node < handle
    
       properties
          coordinate;
       end
    
       methods
           function obj=Node(id)
               obj.coordinate=id;
           end
       end
    
    end
    

    .

    classdef Mesh < handle
    
       properties
          nodes;    % its object will contain an object array of Node
          elements; % its object will contain an object array of Element
       end
    
       methods
           function obj=Mesh(nodes,elements)
               pnodes=cell(1,nodes);
               for idx=1:nodes
                   pnodes{idx}=Node(idx);
               end
               obj.nodes=[pnodes{:}];
               pelements=cell(1,numel(elements));
               for idx=1:numel(elements)
                   pelements{idx}=Element(obj.nodes(elements{idx}));
               end
               obj.elements=[pelements{:}];
           end
           function non_deleted_nodes=get.nodes(obj)
               %getter to return only not-deleted nodes
               obj.nodes=obj.nodes(arrayfun(@isvalid,(obj.nodes)));
               non_deleted_nodes=obj.nodes;
           end
           function non_deleted_nodes=get.elements(obj)
               %getter to return only not-deleted nodes
               obj.elements=obj.elements(arrayfun(@isvalid,(obj.elements)));
               non_deleted_nodes=obj.elements;
           end
    
       end
    
    end
    

    .

    classdef Element < handle
    
       properties
          localNodes; % the object instantiated from the class Element
                      % will store an array of pointers to the
                      % appropriate elements of the object array stored
                      % in Mesh.nodes. How can I assign these pointers
                      % to Element.localNodes?
       end
    
       methods
           function obj=Element(localNodes)
               obj.localNodes=localNodes;
           end
           function non_deleted_nodes=get.localNodes(obj)
               %getter to return only not-deleted nodes
               obj.localNodes=obj.localNodes(arrayfun(@isvalid,(obj.localNodes)));
               non_deleted_nodes=obj.localNodes
           end
           function delete(obj)
               for ix=1:numel(obj.localNodes)
                   %The 1 is not a typo, we will delete always the first
                   %element until the list is empty
                   obj.localNodes(1).delete();
               end
               delete@handle(obj);
           end
       end
    
    end
    

    最后是一个简短的演示:

    m=Mesh(10,{[1,2],[2,3],[3,4]})
    m.elements(1).localNodes
    m.elements(1).localNodes(1).delete()
    %now the node is deleted from the element and the mesh
    m.elements(2).delete()
    %now element 2 together with the nodes is deleted.
    

    【讨论】:

    • 感谢您的课程。两个问题:1)为什么需要delete@handle(obj);? 2)如果我错了,请纠正我。 Element 类需要是句柄类,因为如果我删除一个元素,它的两个节点必须同时从 Element 对象和 Mesh 对象中删除。如果我只想删除节点,那么 Node 类作为句柄类就足够了,因为在这种情况下,我想从元素和网格中删除该节点对象,但元素会保持。重新制定:哪个条件要求 Element 类是句柄类? 3)看我的下一条评论。
    • 3) 我们能否永久删除特定的节点或元素对象,而不仅仅是它的句柄,这样 Mesh 中就不需要 getter 方法了?或者在句柄类的情况下,不能仅删除对象的句柄?
    • 1) 调用不是必需的,我认为需要在句柄中调用delete,但无论如何都会调用它。
    • 3) 我已经更新了代码,它现在会在调用 getter 时永久删除引用。这可以防止不必要的大型数据结构。
    • 2) 使用带有handle 的版本,否则不能使用对元素的引用。
    【解决方案2】:

    您必须使用超类handle,让您使用引用而不是复制数据。

    x=MyValueClass(); %assume handle not superclass
    y=x; %creates a copy
    x=MyHandleClass(); %assume handle is superclass
    y=x; %creates a reference to the same instance
    

    【讨论】:

    • 在类定义中不需要&lt; handle来创建句柄类吗?或者你能定义一个非句柄对象的句柄吗?
    • Daniel,我知道在这种情况下应该使用 classdef Node
    • @AndrasDeak:是的,这正是我的建议。
    • @ZoltánCsáti 您可以为每个节点创建一个新的句柄类对象,如此有效,您可以为每个节点获得一个副本,其优势在于能够更有效地传递它.
    • 啊哈,所以我在上一条评论中附加的代码中的问题可能是 repmat 复制了对同一个对象的引用,这就是为什么我给出相同的 3。但是我怎样才能初始化一个数组来自句柄类的对象,以避免它们被指向同一个对象?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 2016-02-11
    • 2020-07-26
    • 2011-02-07
    • 2022-11-10
    • 2019-08-23
    相关资源
    最近更新 更多