模拟这个'在matlab中的指针

时间:2016-12-03 15:16:28

标签: matlab this function-handle

我有一个类以一种奇怪的方式封装对数组的访问; 类构造函数接受一个函数句柄,它是在将索引传递给数组

之前对索引进行某种转换
classdef MyClass
properties
    arr
    accessHandle
end
methods
function obj = MyClass(array, trans)
    obj.arr = array;
    obj.accessHandle = @(i) obj.arr(trans(i))
end
end

问题是匿名函数将数组复制到它自己的工作区中,如果我们更改数组,它就不会在函数中发生变化。 基本上所需要的是将匿名函数传递给'这个'指针/引用,如Java / C ++ / etc

简单的解决方案是创建数组的句柄并将其传递给函数:

classdef MyClass
properties
    arr
    accessHandle
end
methods
function obj = MyClass(array, trans)
    obj.arr = array;
    tmp = PropertyReference(obj, 'arr'); %See http://stackoverflow.com/questions/7085588/matlab-create-reference-handle-to-variable 
    %for the definition
    obj.accessHandle = @(i) tmp(trans(i));
end
end
end

现在的问题是当我将类的实例传递给函数时,传递的引用仍然引用函数外部的对象:

function foo(ins)
    ins.arr = [1 2];
    disp(ins.accessHandle(1));
end
cl = MyClass([0 3], @(x) x);
foo(cl) //output 0 instead of 1
disp(ins.accessHandle(1)) //output 0

编辑:该类应该是一个值类,语义是当创建类的副本时,accessHandle字段会更改它使用的数组句柄。

如何实现正确的语义?

1 个答案:

答案 0 :(得分:2)

目前,您的类是一个值类(MATLAB的默认值)。如果您希望能够通过引用传递对象(更改将反映在原始对象中),您可以通过继承handle

使其成为handle class
classdef MyClass < handle
    properties
        arr
        accessHandle
    end

    methods
        function obj = MyClass(array, trans)
            obj.arr = array;
            obj.accessHandle = @(i) obj.arr(trans(i))
        end
    end
end

然后你可以按照预期的方式使用它

m = MyClass([1 2 3], @(x)x);

m.accessHandle(2)
%   2

m.arr(2) = 5;

m.accessHandle(2)
%   5

有关两个can be found here之间差异的更多信息。

修改

如果您需要MyClass作为值类,那么您可以将trans值存储为属性,然后使用常规方法来访问该值

classdef MyClass
    properties
        arr
        trans
    end

    methods
        function obj = MyClass(array, trans)
            obj.arr = array;
            obj.trans = trans;
        end

        function res = access(obj, k)
            res = obj.arr(obj.trans(k));
        end
    end
end

或者,如果您愿意,可以使accessHandle为依赖属性,返回函数句柄。

classdef MyClass
    properties
        arr
        trans
    end

    properties (Dependent)
        accessHandle
    end

    methods
        function obj = MyClass(array, trans)
            obj.arr = array;
            obj.trans = trans;
        end

        function res = get.accessHandle(obj)
            res = @(i)obj.arr(obj.trans(i));
        end
    end
end