模拟';这';matlab中的指针

模拟';这';matlab中的指针,matlab,this,function-handle,Matlab,This,Function Handle,我有一个类,它以wierd的方式封装对数组的访问; 类构造函数接受一个函数句柄,它是将索引传递给数组之前的某种类型的转换 classdef MyClass properties arr accessHandle end methods function obj = MyClass(array, trans) obj.arr = array; obj.accessHandle = @(i) obj.arr(trans(i)) end end 问题是匿名函数将数组复

我有一个类,它以wierd的方式封装对数组的访问; 类构造函数接受一个函数句柄,它是将索引传递给数组之前的某种类型的转换

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中的“this”指针/引用

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

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
现在的问题是,当我将类的实例传递给函数时,传递的引用仍然引用函数外部的对象:

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
EDIT:该类应该是一个值类,语义是当复制该类时,
accessHandle
字段会更改它使用的数组句柄


如何实现正确的语义?

当前,您的类是一个值类(MATLAB的默认值)。如果希望能够通过引用传递对象(更改将反映在原始对象中),则需要通过子类化
句柄

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
更多关于两者区别的信息

编辑

如果需要将
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

子类化
handle
能解决这个问题吗?@TroyHaskin@Suever我不能像我在最后一句中解释的那样把它变成一个句柄<代码> Foo>代码不改变输入,只有它的拷贝,即<代码> Access和<代码>的等效C++定义将是<代码> [INT](INTX){返回-> ARR(反(X));} < /Cord>如果您没有编写<代码> ARR < /Cord>句柄;您正在使
MyClass
成为具有指针语义的
handle
class对象@Suever的回答似乎有你想要的行为。如果缺少,请用一个更具说明性的例子加以说明。@TroyHaskin参见编辑和代码的新的最后一行参见编辑,该类应该是一个值类,更改仅用于定义
accessHandle
@Omerosler为什么它需要是一个值类?如果没有句柄类,你就不能这样做。@Omerosler还有,为什么你不能将对象传递到
accessHandle
匿名函数中?@Omerosler,或者让
accessHandle
成为一个真正的方法好了,这个类是一个数组,它具有值类的语义;access函数需要类的句柄,而不是类本身