学习笔记----MATLAB的句柄类和实体值类

本系列内容为《MATLAB面向对象编程–从入门到设计模式》学习笔记,特此说明。

Value类和Handle类

MATLAB面向对象编程中有两种类:一种叫叫做Value类(Value Class),即数值类;另一种叫做Handle 类(Handle Class),也叫句柄类或引用类。

两者区别:定义的类是否继承了MATLAB内部提供的一个Handle基类。

%Value 类
classdef SomeValue
    properties
        valValue
    end
    methods
        function obj = SomeValue(N)
            obj.valValue = N;
        end
    end
end

%Handle 类
classdef SomeHandle < handle  %区别
    properties
        ValHandle
    end
    methods 
        function obj = SomeHandle(N)
            obj.ValHandle = N;
    end
end

Value类对象和Handle类对象区别

复制时区别

clear all;clc;

mValue = SomeValue(10);
mHandle = SomeHandle(10);

%复制
nValue = mValue;
nHandle mHandle;

MATLAB对于Value类对象在内存中做了完全的拷贝,也叫深拷贝。

而对于Handle类对象,MATLAB只复制Handle类对象本身,而没有复制句柄对象指向得到实际数据。Handle类对象的复制不是一个完全的复制,不是一个深拷贝(Deep Copy),而是一个浅拷贝(Shallow Copy),因为没有深入到Handle类所指向的数据对实际数据进行复制。

Value 类对象和Handle类对象当做函数参数时区别

对于Value类对象,参数的传递方式是:复制必要的信息到函数工作空间中,当MATLAB发现该函数对传入的参数进行了修改,并且该参数时Value类对象时,MATLAB就构造出一个局部拷贝。

Handle类对象,参数传递方式也是赋值局部对象,但在函数内部,函数修改的不是针对Handle 类对象所指向的数据,所以,MATLAB内部并不需要做额外的处理,并且该函数成功地修改了Handle类对象所指向的数据。

综上所述,Handle类对象可以用来在函数中修改传来的参数。

MATLAB对参数的处理方式:如果希望在函数体内修改参数,则需要传递Handle类对象;否则就要使用Value类,并且把修改完的对象当做结果返回。

使用Value类或Handle 类的情况

Value类较为适合比较简单的数据,其行为和MATLAB的普通变量、matrix、struct、cell基本一致,他们完全由其所含的数据值类定义。若不介意副本的存在,并且希望每次执行对象的复制时都可以得到一个独立的副本,则适合使用Value类。如果一个数据在其他多处都有副本,并且希望修改其中的副本时其他所有的副本都会受到影响,也被修改,则使用Handle类。

Handle类对象提供的是对实际数据的一个访问渠道,从实用计算的角度来说,如果数据体积比较大,并且希望这些数据在各个方法、函数之间传递迅捷,不需要被局部复制,则可以使用Handle类来包装该数据。

从物理的角度来看,如果类的对象对应一个具体的物理对象,比如一个串口、一个窗口等,应该将其设计成Handle类,因为对这些对象进行复制仅仅是访问他们的一个渠道。

从功能的角度来看,Value类没有提供任何内置的方法,而Handle基类提供了delete方法,可以定义events和addlistener方法等,使Handle类的功能更加强大。

从性能的角度来看,因为Handle 类对象其实是内部数据的一个全权代理,对Handle类属性的访问经历了一个中间层的代理,因此Handle 类对象属性的访问速度比Value类对象属性访问速度稍慢。

 

类的析构函数(Destructor)

对象的生存周期

在MATLAB中,不论对象还是普通变量,都占用内存,不需要时要释放占用的内存资源。

所谓对象的生存周期,是指对象从产生到释放的过程。

析构函数

析构函数在对象脱离其作用域或者被销毁时负责收尾工作,比如关闭文件句柄、释放数据所占的内存空间等。MATLAB规定,对执行这种任务的类方法要命名为delete.

无论是Value类还是Handle 类,如果在对象的清除过程中涉及释放其占用的系统资源,那么需要自己定义delete函数。

Value 类本身不存在默认的delete方法,所以如果不定义delete方法,那么就无法对其使用delete 方法。

Handle类需要继承一个Handle的基类,该基类中已经定义了一个delete方法,可以直接对Handle 类对象使用delete方法。对Handle 类对象使用delete将释放该Handle 所指向的数据。

MATLAB提供一个isvalid函数,用来检查Handle类对象是否有指向任何实际的数据。该函数对失效的Handle 类对象返回false。

 

需要自定义delete方法的情况

当类的对象占用了一些系统资源而无法自动释放时,需要自动重载一个delete 方法来释放这些系统资源。比如Value类或Handle类中,构造函数打开了一个文件句柄,则需要在delete 方法中关闭这个文件句柄。

%Value类
classdef AVal 
    properties
        fid = fopen('file.txt');
    end
    methods
        function delete(obj)
            fclose(obj.fid);
        end
    end
end

%Handle类
classdef BVal < handle
    properties
        fid = fopen('file.txt');
    end
    methods
        function delete(obj)
            fclose(obj.fid);
        end
    end
end

对于普通的属性,MATLAB在销毁对象时会自动释放这些属性所占用的内存,而没有必要专门定义delete方法来删除对象中的某个属性。

Value类没有析构函数

对于Value类而言,Value类的delete 方法只是自定义的一个方法,不是MATLAB承认的合法析构函数,所以该函数的名字是可以任意命名的。这个方法的存在主要是提醒不要忘记释放资源,由于它的delete 方法不是析构函数,MATLAB不会自动调用,需要显式地调用它。

MATLAB会自动调用Handle类对象的析构函数

对于Handle类而言:MATLAB Handle基类已经提供了基本的delete方法的实现方法,如果有额外的需要,则必须在子类中重载这个delete方法。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值