2016-12-03 138 views
1

我有一个封装以奇怪方式访问数组的类; 类构造函数需要一个功能手柄,该手柄是某种指标的改造将它们传递给数组在matlab中模拟'this'指针

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

问题是匿名函数将数组到它自己的工作区之前,如果我们改变阵列,它在功能中不会改变。 基本上所需要的是传递到匿名函数的this指针/参考象Java/C++ /等

的简单的解决方案是创建一个手柄到阵列并将其传递给该函数:

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字段将更改它使用的数组句柄。

我该如何实现正确的语义?

+2

将子类'handle'解决这个问题吗? – TroyHaskin

+0

@TroyHaskin @Suever我不能像我在最后一次交待中解释的那样使它变成句柄; 'foo'不改变输入,只是它的副本 –

+0

'accessHandle'的等效C++定义是'[this](int x){return this-> arr(trans(x));}'如果这有帮助 –

回答

2

目前,你的类是一个值类(MATLAB的默认值)。如果你希望能够通过传递引用的对象(变化将反映在原始对象),你会通过继承handle

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 

,使之成为handle class然后你就可以使用它,你的方式预计

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 
+0

请参阅编辑,类应该是一个值类,这个改变只是为了'accessHandle'的定义 –

+0

@OmerRosler为什么它需要成为价值课吗?如果没有句柄课程,你就无法做到这一点。 – Suever

+0

@OmerRosler另外,为什么你不能将对象传递给'accessHandle'匿名函数呢? – Suever