Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过继承修改所有实例的MATLAB字段访问?_Matlab_Oop_Inheritance - Fatal编程技术网

通过继承修改所有实例的MATLAB字段访问?

通过继承修改所有实例的MATLAB字段访问?,matlab,oop,inheritance,Matlab,Oop,Inheritance,我正在尝试使用MatlabOOP功能为网格开发数据结构。长话短说,我正在修改一个实例中的字段,该实例继承自与另一个实例相同的基类,并且两个实例都在被修改,就好像该字段被声明为静态的一样 我在MATLAB中的抽象基类(m_元素)中有以下代码: properties(Access = protected) nodes = containers.Map('KeyType','int64', 'ValueType', 'any'); faces = containers.Map('Key

我正在尝试使用MatlabOOP功能为网格开发数据结构。长话短说,我正在修改一个实例中的字段,该实例继承自与另一个实例相同的基类,并且两个实例都在被修改,就好像该字段被声明为静态的一样

我在MATLAB中的抽象基类(m_元素)中有以下代码:

properties(Access = protected)
    nodes = containers.Map('KeyType','int64', 'ValueType', 'any');
    faces = containers.Map('KeyType','int64', 'ValueType', 'any');
end
这些字段表示每个元素的连接性。例如,哪些节点是第n个节点的邻居,或者哪些面与第n个节点相邻

我还有另外两个类:m_face和m_node,每个类都继承自m_元素。 m_节点非常简单:

classdef m_node < m_element
    properties
        x = 0;
        y = 0;
        z = 0;
    end

    methods
        function node = m_node(gmsh_id, x, y, z)
            node = node@m_element(gmsh_id);

            node.x = x;
            node.y = y;
            node.z = z;
        end
    end
end
m_face构造函数希望face ID作为第一个参数出现,其余的应该是构成face的节点。行
face.nodes(nod.gmsh_id)=nod似乎是导致我的问题的原因。我有一个m_网格类,它将容纳每个节点和面:

classdef m_mesh < handle
    properties(SetAccess = private)
        nodes = containers.Map('KeyType','int64', 'ValueType', 'any');
        faces = containers.Map('KeyType','int64', 'ValueType', 'any');
    end

    methods

        function theMesh = m_mesh(msh)
            for idx = 1:numel(msh.POS(:,1))
                n = msh.POS(idx,:);
                theMesh.nodes(idx) = m_node(idx, n(1), n(2), n(3));
            end

            for idx = 1:numel(msh.TRIANGLES(:,1))
                ele = msh.TRIANGLES(idx,:);
                nod(1) = theMesh.nodes(ele(1));
                nod(2) = theMesh.nodes(ele(2));
                nod(3) = theMesh.nodes(ele(3));

                theMesh.faces(idx) = m_face(idx, nod(1), nod(2), nod(3));
            end
        end
    end
end

i_节点返回实例映射值。那怎么可能呢?如果我还没有设置,为什么我的第一个(以及所有其他!)节点有五个相邻的节点?当我从随机实例访问此字段时,为什么MATLAB要更改所有实例和所有子类的非静态字段?

您应该初始化构造函数中的
节点
属性,而不是默认属性值

这是怎么回事?首先要注意的是,
containers.Map
是一个
句柄

MATLAB中的正常变量具有值行为:

>> a = 1;
>> b = a;
>> a = 2;
>> b
b =
     1
>> a = figure;
>> b = a;
>> get(a, 'Name')
ans =
     ''
>> get(b, 'Name')
ans =
     ''
>> set(a, 'Name', 'hello')
>> get(b, 'Name')
ans =
hello
请注意,
b
在您更改
a
时没有更改-它是
a
的副本,
a
b
是具有传递值行为的值变量

其他一些变量具有句柄行为:

>> a = 1;
>> b = a;
>> a = 2;
>> b
b =
     1
>> a = figure;
>> b = a;
>> get(a, 'Name')
ans =
     ''
>> get(b, 'Name')
ans =
     ''
>> set(a, 'Name', 'hello')
>> get(b, 'Name')
ans =
hello
请注意,当您更改
a
时,
b
已更改-它是对
a
的引用,
a
b
是具有传递引用行为的句柄变量

containers.Map
变量是句柄变量

第二件需要注意的事情是,属性默认值在类第一次实例化时计算一次。(如果您使用
清除类
清除类定义,则下次实例化时将再次对其求值)。它们不会在每次创建对象时进行计算

因此,第一次创建对象时,类被实例化,计算
containers.Map
,之后的每个对象都将获得与其属性相同的
containers.Map
。由于它是一个句柄变量,因此对一个对象中的属性所做的更改将在其他对象的属性中引用

您不希望这样:相反,您应该初始化类构造函数中的值。然后,每次构造对象时,它都会被单独计算,并且每个对象都会得到一个单独的对象


这种行为(即,当您将变量处理为属性默认值时)可能会令人困惑,但我认为这是正确的行为——它是有文档记录的,尽管我认为它可以更清楚地标示出来。这里是讨论这个话题的地方——在评论中,作者、我和一位负责OO语法和设计的MathWorks开发人员讨论了这个问题。

Dude!谢谢这让我疯狂。我一定会阅读文章。你知道,我以前习惯于用C++、java和其他OO语言编程。所以这种行为并没有发生在我身上,即使我已经习惯了值/句柄二元性。现在我明白了。