matlab编辑程序出现“结构体内容引用自非matlab 结构体数组组对象。”的问题,该如何解决啊

matlab出错:在不同结构体之间进行下标赋值
【系统环境】windows 8【操作内容】matlab2014a【解决方案验证次数】1次一、出现问题在赋值结构体的数组时,出现:在不同结构体之间进行下标赋值:
出错test(line 25)
st.ch(2) =二、根本原因matlab结构体的赋值顺序必须相同才算是相同的结构体三、解决方法将结构体赋值顺序统一:c.ia = 1;
c.ib = [];
d.ib = [];
root.ch(1) =
root.ch(2) =ia,ib,ic对应进行赋值,不要调换顺序,就不会报错了。
1、转载请注明出处:http://www.bewindoweb.cn/157.html
2、本作品遵循分享许可方式:帐号:密码:下次自动登录{url:/nForum/slist.json?uid=guest&root=list-section}{url:/nForum/nlist.json?uid=guest&root=list-section}
贴数:12&分页:xxkui 对弈提高慢,悬牌且免战发信人: KOWCC (xxkui 对弈提高慢,悬牌且免战), 信区: MathTools
标&&题: 问一下matlab结构体引用的问题
发信站: 水木社区 (Tue Jan 20 11:21:42 2015), 站内 && foo.num=3
foo.str='blabla' && 除了用foo.num引用3这个值,还有其他办法么。
譬如有某个函数func_foo(foo,1),可以实现获取结构体foo第1个数据。 && 之所以这样问,是因为我一系列结构体数组,比如
foo1,foo2,foo3....
每个变量都是一个结构体数组,不同的数组中的结构体的具体数据项不一致,但是每个里面都有一个关键字,可以用来排序。 && 现在要编写个排序函数(譬如最简单的冒泡排序)
如果不能实现我要求的那种引用,难道得给每个结构体单独编写一个排序函数吗。。。 && 另外,是不是可以用eval之类的实现呢?
譬如排序函数这样定义:
sort(structname,key_item)
调用时:sort('foo1','numoffoo1')
函数体里有类似这样的东西:
for i=1 :N
str1=[structname '(i).' key_item];
str2=[structname '(j).' key_item]; && str_comp=['if' str1 '&' str2 交换]
eval(str_comp)
end && 但是感觉好麻烦 && --
请一定开出永不凋落的希望之花 &&&& ※ 修改:·KOWCC 于 Jan 20 11:23:01 2015 修改本文·[FROM: 166.111.73.140]
※ 来源:·水木社区 newsmth.net·[FROM: 166.111.73.140]
xxkui 对弈提高慢,悬牌且免战发信人: KOWCC (xxkui 对弈提高慢,悬牌且免战), 信区: MathTools
标&&题: Re: 问一下matlab结构体引用的问题
发信站: 水木社区 (Tue Jan 20 11:50:47 2015), 站内 && 嗯,算是搞定了。
以下是我写的函数:
function result = SortStruct(foo,keyitem )
%该函数给名为foo的结构体排序
%排序的关键字为字符串keyitem,对应foo里的一个数据项名称
N=max(size(foo));
for i=1:N &&&& for j=i+1:N &&&&&&&& stri=['foo(i).' keyitem]; &&&&&&&& strj=['foo(j).' keyitem]; &&&&&&&& comp_str1=['if ' stri '&' strj]; &&&&&&&& comp_str2=['tmp=foo(i);foo(i)=foo(j);foo(j)=']; &&&&&&&& comp_str3=['end']; &&&&&&&& eval([comp_str1 13 comp_str2 13 comp_str3 13]); &&&& end
高手给提点意见,刚才发问的时候才想起eval这个东西,以前用的很少。
感觉很麻烦,用起来还好。 && 另外问问有没有不用eval的方法。
【 在 KOWCC (xxkui 对弈提高慢,悬牌且免战) 的大作中提到: 】
: foo.num=3
: foo.str='blabla'
: 除了用foo.num引用3这个值,还有其他办法么。
: ...................
请一定开出永不凋落的希望之花 &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 166.111.73.140]
归心发信人: guixin (归心), 信区: MathTools
标&&题: Re: 问一下matlab结构体引用的问题
发信站: 水木社区 (Tue Jan 20 19:02:49 2015), 站内 && 你这么写这个功能,就发挥不了MATLAB的特长了,简洁才是MATLAB的美 && keyArray = [foo.keyitem];
[~,aIdx,bIdx] = sort(keyArray);
foo = foo(bIdx); && 就实现了所需的功能吧
手头没有MATLAB,命令可能记得不准,你调试看看 && 【 在 KOWCC (xxkui 对弈提高慢,悬牌且免战) 的大作中提到: 】
: 嗯,算是搞定了。
: 以下是我写的函数:
: function result = SortStruct(foo,keyitem )
: ...................
&& -- && ※ 来源:·水木社区 newsmth.net·[FROM: 114.245.103.*]
xxkui 对弈提高慢,悬牌且免战发信人: KOWCC (xxkui 对弈提高慢,悬牌且免战), 信区: MathTools
标&&题: Re: 问一下matlab结构体引用的问题
发信站: 水木社区 (Tue Jan 20 19:04:12 2015), 站内 && 那个~看起来很高大上啊
你这个思路好,利用系统函数,别自己写。
我回头试试。
【 在 guixin (归心) 的大作中提到: 】
: 你这么写这个功能,就发挥不了MATLAB的特长了,简洁才是MATLAB的美
: keyArray = [foo.keyitem];
: [~,aIdx,bIdx] = sort(keyArray);
: ...................
请一定开出永不凋落的希望之花 &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 183.173.36.90]
xxkui 对弈提高慢,悬牌且免战发信人: KOWCC (xxkui 对弈提高慢,悬牌且免战), 信区: MathTools
标&&题: Re: 问一下matlab结构体引用的问题
发信站: 水木社区 (Tue Jan 20 19:24:15 2015), 站内 && 请问sort里面有这个功能吗
我传一个数组进去,回来以后有元数组元素的排序信息。
a=[10 30 40 20 50];
输出是这样的:[1 3 4 2 5]
意思是说10排在第一,30排第三,这样的
【 在 guixin (归心) 的大作中提到: 】
: 你这么写这个功能,就发挥不了MATLAB的特长了,简洁才是MATLAB的美
: keyArray = [foo.keyitem];
: [~,aIdx,bIdx] = sort(keyArray);
: ...................
请一定开出永不凋落的希望之花 &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 183.173.36.90]
归心发信人: guixin (归心), 信区: MathTools
标&&题: Re: 问一下matlab结构体引用的问题
发信站: 水木社区 (Tue Jan 20 19:27:07 2015), 站内 && aIdx,bIdx里面有一个是,我忘了哪一个了
你看看 && 【 在 KOWCC (xxkui 对弈提高慢,悬牌且免战) 的大作中提到: 】
: 请问sort里面有这个功能吗
: 我传一个数组进去,回来以后有元数组元素的排序信息。
: ...................
&& -- && ※ 来源:·水木社区 newsmth.net·[FROM: 114.245.103.*]
xxkui 对弈提高慢,悬牌且免战发信人: KOWCC (xxkui 对弈提高慢,悬牌且免战), 信区: MathTools
标&&题: Re: 问一下matlab结构体引用的问题
发信站: 水木社区 (Wed Jan 21 11:57:25 2015), 站内 && 高手,对结构体很熟悉啊,我很少用结构体,你这个第一行,我可能只会这么写: && for i=1:max(size(Kfoo))
KeyArray(i)=foo(i).
end && 再请教一个问题:
一个结构体A,里面的其中一项是结构体B,B里面有一项是B_x
现在用结构体A组成一个n维的结构体数组A_array,想构建一个关于B_x的n维数组B_x_array && 用[A_array.B]可以获得一个关于B的结构体数组
但是不能直接这样获得B_x数组:[A_array.B].x && 目前我只能这样:tmp=[A_array.B];B_x_array=[tmp.x]; && 可以有仅一行就达到目的的方式么。 && thx && 【 在 guixin (归心) 的大作中提到: 】
: 你这么写这个功能,就发挥不了MATLAB的特长了,简洁才是MATLAB的美
: keyArray = [foo.keyitem];
: [~,aIdx,bIdx] = sort(keyArray);
: ...................
请一定开出永不凋落的希望之花 &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 183.173.35.44]
accumarray发信人: accumarray (accumarray), 信区: MathTools
标&&题: Re: 问一下matlab结构体引用的问题
发信站: 水木社区 (Fri Jan 23 11:19:20 2015), 站内 && 举个简单的例子:
A(3).B.X = 3;
A(2).B.X = 2;
A(1).B.X = 1;
arrayfun(@(x)x.X,[A.B])
【 在 KOWCC 的大作中提到: 】
: 高手,对结构体很熟悉啊,我很少用结构体,你这个第一行,我可能只会这么写:
: for i=1:max(size(Kfoo))
: KeyArray(i)=foo(i).
: ...................
&& -- && ※ 来源:·水木社区 ·[FROM: 106.39.80.*]
xxkui 对弈提高慢,悬牌且免战发信人: KOWCC (xxkui 对弈提高慢,悬牌且免战), 信区: MathTools
标&&题: Re: 问一下matlab结构体引用的问题
发信站: 水木社区 (Fri Jan 23 11:59:58 2015), 站内 && 用到函数句柄了啊,以前不知道这玩意儿,高大上!
函数句柄有更广泛的应用吗?
【 在 accumarray (accumarray) 的大作中提到: 】
: 举个简单的例子:
: A(3).B.X = 3;
: A(2).B.X = 2;
: ...................
请一定开出永不凋落的希望之花 &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 166.111.73.140]
xxkui 对弈提高慢,悬牌且免战发信人: KOWCC (xxkui 对弈提高慢,悬牌且免战), 信区: MathTools
标&&题: Re: 问一下matlab结构体引用的问题
发信站: 水木社区 (Fri Jan 23 12:17:40 2015), 站内 && 另外,这个倒叙方式是你的习惯?
A(3)先给数组开辟三个单元,然后2,1填进去。
A(1),A(2),A(3)是要动态扩充3次再填进去。
所以说前者效率更高?
【 在 accumarray (accumarray) 的大作中提到: 】
: 举个简单的例子:
: A(3).B.X = 3;
: A(2).B.X = 2;
: ...................
请一定开出永不凋落的希望之花 &&&& ※ 来源:·水木社区 newsmth.net·[FROM: 166.111.73.140]
文章数:12&分页:「七」MATLAB语言之结构体(struct)操作「七」MATLAB语言之结构体(struct)操作第一人称百家号MATLAB语言中实现比较复杂的编程,就不得不使用struct类型。在MATLAB中实现struct比在C语言中更为方便。MATLAB中的结构体:结构是包含一组记录的数据类型,而数据则是存储在相应的字段中。结构的字段可以是任意一种MATLAB数据类型的变量或者对象。结构类型的变量可以是一维的、二维的或多维的数组。结构体也叫结构数组,架构数组。不过,在访问结构体类型的元素时,需要使用下标配合字段的形式。可以在一个结构体中放置各类的数据,并且一个结构体还能是另一个结构体的一部分(即结构体的嵌套使用)。相比较而言,比元胞数组更为强大,也更加富于变化。结构体的创建MATLAB提供了两种定义结构体的方式:直接引用和使用struct函数。与建立普通数组一样,建立新的struct对象不需要事先声明,可以直接引用,而且可以动态扩充。使用struct函数也可以创建结构体,该函数产生或把其他形式的数据转换为结构体,其调用格式为:str_array=struct('field1',{val1},'field2',{val2}...);结构体操作函数MATLAB中专门用于对结构体操作的函数并不多,如下所示。struct:创建结构或将其他数据类型转变成结构;fieldnames:获取结构的字段名称;getfield:获取结构的字段数据;setfield:设置结构的字段数据;rmfield:删除结构的指定字段;isfield:判断给定的字符串是否为结构的字段名称,是,返回真,否,返回假;isstruct:判断给定的数据对象是否为结构类型,是,返回真,否,返回假;orderfields:将结构字段排序,按ASCII码排序。最后,感谢您的耐心阅读!本文由百家号作者上传并发布,百家号仅提供信息发布平台。文章仅代表作者个人观点,不代表百度立场。未经作者许可,不得转载。第一人称百家号最近更新:简介:用第一人称记录眼前所有的发生作者最新文章相关文章matlab 数组元素相加提示我要“尝试引用非结构体数组的字段。”_百度知道
matlab 数组元素相加提示我要“尝试引用非结构体数组的字段。”
完全无法理解matlab发什么神经
我有更好的答案
从出错提示和你的程序代码看,错在114行ii2=Tji2(i.j)*(hji(i,j)+0)中Tji2(i.j),应该改为Tji2(i,j)
采纳率:77%
来自团队:
应该是Tji2(i,j) % 注意是逗号,你不小心写成.了,系统默认为是结构体了
本回答被提问者采纳
应该是Tji2(i,j) % 注意是逗号,你不小心写成.了,系统默认为是结构体了
为您推荐:
其他类似问题
英语的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。MATLAB面向对象编程模式下 - 简书
MATLAB面向对象编程模式下
因为简书字数限制,完整版地址:
如有错误,烦请指正!
第11章 对象数组
11.1 如何把对象串接成数组
串接:使用方括号[]把已有的变量组合起来,使其成为一个数组。使用这种方式构造的对象数组,适用于对象数量比较少的情况。对objArray中对象元素的访问和普通数组中元素的访问是一样的。在此基础上使用点+属性名称的语法,可以访问对象元素的属性。
objArray=[b1 b2 b3];
objArray(1).a=10;
11.2 如何直接声明对象数组
自动生成一个1*10的数组,并把第10个元素置为1,其余为没有被赋予初值的元素,用0作为其初值。
array(1,10)=1;
对象扩展:objArray(1,10)=Square(5);
MATLAB解释器会把这个命令翻译成如下指令:对第10个元素调用Square(5);其余的1-9个元素调用缺省的构造函数。缺省的构造函数只被调用一次,产生了一个对象,其余的都是直接拷贝对象。调用缺省的构造函数说明函数要考虑输入0参数的情况。在此扩展的对象数组是handle类的,尽管其内部数据的数值相同,但如果直接比较被拷贝的元素,它们的handle仍然是不同的。
注意Value类对象没有定义==运算符,所以为了比较两个对象,需要重载==(eq)运算符。
11.3 如何使用findobj寻找特定的对象
首先使用串接语法,构造一个对象数组。然后使用逻辑‘-and’或者‘-or’关键词,在findobj函数中查找指定对象。
11.4 如何利用Cellarray把不同类的对象组合到一起
MATLAB规定对象数组中元素的种类必须保持一致,如果不一致,matlab就会尝试把一个对象转换成另一个,如果找不到可以使用的对象转换函数,MATLAB就会报错。最简单的解决办法就是使用元胞数组(Cell Array),元胞数组是MATLAB中专门用来存放不同种类数据的工具。例如:
o1=Square();
o2=Circle();
oCell={o1,o2}
oCell{1}.a%访问CellArray中的一个元素
使用Cell取代array,简单实用,但是没有办法利用向量化式地方式集中访问数组中对象内部的元素。
11.5 什么是转换函数
定义:一种负责把该类的对象转换成其他类的对象的一种类的方法。
只需要在该类中定义转换函数,则调用的时候就能完成转换。转换函数只需要调用转换对象的Constructor。
11.6 如何利用转换函数把不同类的对象组合到一起
转换函数一般是隐式转换。假设数组的第一个为Square对象,则第二个赋值时需要检查,如果不相同,则需调用第二个对象的转换函数。如果没有定义转换函数,MATLAB会直接把第二个对象作为参数提供给square的构造函数。如果无法处理,MATLAB会报错。
11.7 如何用非同类(Heterogeneous)数组盛放不同类对象
11.7.1 为什么需要Heterogeneous数组
转换函数把不同类型的对象组合到一起,并且不改变对象的类型。
使用Heterogeneous需要两个类具有共同的父类,并且父类继承自一个叫做Heterogeneous的基类。
基类声明:
classdef Shape2D&handle&matlab.mixin. Heterogeneous
不用定义convert函数,不存在对象之间的相互转换;
构造出的数组可以存放共同基类的对象;
可以使用数组的下标语法,向量化访问对象的共同特征;
可以使用对象的共同方法,必须是Sealed。
11.7.2 含有不同类对象的数组类型
包含有不同对象的数组类型,总是取对象们最近的共同父类。
11.7.3 使用Heterogeneous要避免哪些情况
1、没有除Heterogeneous之外的共同的父类。
2、多重继承存在交叉继承,这时候也不能将子类的对象放到一个对象数组中去。
11.7.4 如何向量化遍历数组中对象的属性
如果用Dot语法访问数组中对象的共同属性,返回的结果将是一个用都好分隔的list。
11.7.5 如何设计成员方法使其支持向量化遍历
s=objArray.area
objArray被当做一个参数传入area方法中。
如果是HeterogeneousArray,想要支持向量化访问的成员方法,必须将其声明成sealed,禁止子类中有不一致的定义。
对象数组是否可以向量化调用destructor?
destructor禁止定义成Sealed,否则子类资源可能无法释放。但是MATLAB对delete方法仍支持使用objArray.delete的格式调用对象们的析构函数。MATLAB并没有向量化地调用对象们的析构函数,因为根本不存在这样一个共同的delete方法。objArray.delete这里为:逐个调用每个对象的析构函数。
第12章 类的运算符重载
12.1 理解MATLAB的subsref和subsasgn函数
12.1.1 MATLAB如何处理形如a(1,:)的表达式
A(1:2,:)会被MATLAB解释器转换成一个subsref的函数调用。该函数的第一个参数是要访问的数据A;第二个参数是要访问元素所在的位置,并且该位置信息存放在一个结构体中。subsref(A,s);例如A(1:2,:),这里s.type=’()’;s.subs={1:2,’:’};也可以通过以下方法访问数组元素:
s.type=’()’;
s.subs={1:2,’:’};
subsref(A,s);
对数组元素的赋值会被Interpreter转换成一个subsasgn的函数调用,例如:
A(1,1)=0;被转换成subsasgn(A,s,0),其中s是一个结构体,
可以通过以下实现A(1,1)=0:
s.type=’()’;
s.subs={1,1};
subsasgn(A,s,0);
12.1.2 MATLAB如何处理形如a{1,:}的表达式
对元胞数组B第一列的访问B{:,1}将会被Interpreter转换成如下的subsref函数调用:
s.type=’{}’;
s.subs={‘:’,1};
subsref(B,s);
对元胞数组B的第一个元胞的赋值:
B{1,1}=0;将被MATLAB转换成如下subsasgn函数调用。
s.type=’{}’;
s.subs={1,1};
subsasgn(B,s,0);
12.1.3 MATLAB如何处理形如s.f的表达式
对struct的访问和赋值也可以直接通过直接调用内置函数来完成。
days.f1和以下等价
s.type=’.’;
s.subs={‘f1’};
subsref(days,s);
days.f3=’NULL’ 和以下等价
s.type=’.’;
s.subs={‘f3’};
subsref(days,s,‘NULL’);
12.2 如何重载subsref函数
数组、矩阵、元胞数组、对象都支持上面的等价调用。形如subsref(obj,s)的调用,优先调用用户自定义的方法。
12.3 如何重载subsasgn函数
优先调用用户自定义的方法。
重载的时候需要返回obj.matrix和obj.cell因为该重载函数的任务是修改对象的属性,但是obj.matrix和obj.cell不是handle对象,所以在函数内部的修改仅仅是局部修改,必须将它传回来。
重载subsasgn和subsref,将会重载该类的属性访问权限,使用时要慎重。
12.4 什么情况下重载下标运算符
当用户想完全禁止通过dot来访问对象内部属性时,可以重载subsref函数。
当用户想构造一个对象,使其行为看上去像函数 一样,可以重载subsref函数。
当用户想在赋值对象数组时,做更多的检查和限制,可以重载subsasgn函数。
让一个标量对象行为像矢量一样。
注意:使用自定义的下标运算符取代内置定义的下边运算符应当是一个方便编程的手段,不应该使用在对性能要求很高的程序中。
12.5 如何重载plus函数
MATLAB中+默认是做算数运算,所以在内部会把string转换成数字,调用plus函数。
12.6 MATLAB的Dispatching规则是什么
对于形如obj.foo(arg1,arg2,arg3)的调用,Dispatcher会直接检查obj类定义中是否定义了foo的方法,如果定义了,那就调用;没有定义,报错。
形如foo (obj,arg1,arg2,arg3),Dispatcher不会首先检查obj类定义中是否定义了foo的方法,而是首先检查四个参数obj,arg1,arg2,arg3哪个参数所属的类是更高级别的类,即为dominant类,然后查找dominant类中是否定义了foo方法,如果定义就调用;没有定义,报错。
类的级别:任何用户定义的类,级别高于MATLAB内置的类。
指定用户定义的类之间的级别
classdef (InferiorClasses={?A,?B})C
C的级别比A和B的高,如果这三类出现在参数列表中,C的对象是dominant对象。
12.7 如何判断两个对象是否相同
handle对象,==运算时在handle中就定义好的算法,用于检查handle类所指向的实际数据时同一个。handle对象的拷贝是浅拷贝,只复制了类中的地址,没有复制类中实际指向的数据对象。
Value类数据,没有定义‘==’运算符,需要用户自己指定行为。
12.8 如何让一个对象在行为上像一个函数
仿函数:使普通函数具有类的功能。
12.9 MATLAB中哪些算符允许重载
第13章 超类
13.1 什么是超类(MetaClass)
定义:用一种普遍的方式来描述类,即用类的方式来描述类。
13.2 如何获得一个类的meta.class对象
第一种得到meta对象的方法是:已知类的名字,可以在类名前面加上一个问号来获得meta.class例如:metaObj=?FileIterator。
第二种方法是:如果有了一个类的对象,可以用meta.class函数来获得meta.class对象,如:metaObj=metaclass(obj);
第三种方法最灵活:如果类的名字是以字符串的形式存在的,可以利用meta.class类中的成员方法fromName,该函数接受string input,返回meta.class对象,例如:name=’Vehicle’;metaObj=meta.class.fromName(name);
13.3 meta.class对象中有些什么内容
如何系统地获得类中所有property的名字?
metaobj=?D
propNameList={metaobj.PropertyList.Name}
metaobj.PropertyList是一个对象数组,其中的内容是meta.property的对象
使用.语法可以向量化访问数组中对象的共同属性
metaobj.PropertyList.Name返回的结果是string类型,由于string的长度不同,使用{}把返回的结果收集到元胞数组中去。
13.4 如何手动克隆一个对象
handle类的浅拷贝
对象的属性相互关联,不独立,俗称浅拷贝。
优点:实现简单。
缺点:如果要克隆有很多的属性,那么一个一个键入属性会很麻烦。
方法1:构造一个方法,先在该方法中声明一个新的对象,叫做newObj,再把旧的对象每一个属性的值都复制到新的对象newObj中,最后在将该newObj返回。
方法2:用meta.class函数,先获得该类的metaObject,然后取出其中的propertyList中属性的名字,然后遍历赋值即可。
该方法中newobj.(props{j})=obj.(props{j})有一个隐藏的前提,所有的property都是Value类型的对象,如果有一个property是handle类型的,则得到的拷贝仍然是浅拷贝。
为了解决仍然是浅拷贝的问题,用户需要提供两个类的clone函数
classdef Ref&handle
properties
function obj=Ref()
obj.a=rand(1);
obj.bobj=BH
function newobj=clone(obj)
newobj=Ref();
metaobj=metaclass(obj);%得到meta Object
props={metaobj.PropertyList.Name};%得到props名字
for j=1:length(props)
tmpProp=obj.(props{j});
if(isa(tmpProp,'handle'))%调用该类的Prop方法
newobj.(props{j})=tmpProp.clone();
newobj.(props{j})=tmpP
classdef BHandle&handle
properties
function obj=BHandle()
obj.var=rand(1);
function newobj=clone(obj)
newobj=BHandle();
metaobj=metaclass(obj);%得到meta Object
props={metaobj.PropertyList.Name};%得到props名字
for j=1:length(props)
tmpProp=obj.(props{j});
if(isa(tmpProp,'handle'))
newobj.(props{j})=tmpProp.clone();%程序不会运行到这里
newobj.(props{j})=tmpP
13.5 如何使用matlab.mixin.Copyable自动克隆一个对象
MATLAB提供mixin类的Copyable,其中包括copy和copyElement两个方法帮助用户完成基本的handle类对象的深拷贝。copy方法是sealed,不允许子类重载,copyElement是protected,允许子类重载。用户只需要让自己的类继承自matlab.mixin.Copyable即可,此时仍为handle类。和前面类似,copy和copyElement组合在一起也是自动遍历的对象中的各个属性做拷贝。
record1=StudentRecord();
record1.name='A';
record2=copy(record1);
record2.name='B';
record1.name
record2.name
copyable类中的方法默认的并不包括对属性做递归的深拷贝,如果对象有一个handle对象,使用copy方法进行对象拷贝时,该对象被浅拷贝。
用户可以重载copyElement方法。先在copyElement中调用父类的copyElement方法,得到新的StudentRecord对象,这时homework属性是浅拷贝。然后对其中的homework属性做完全的复制。
第14章 面向对象程序设计的基本思想
14.1 单一职责原则
一个类最好只有一个引起它变化的因素。
UML,实心菱形表示非包括不可的组合关系;空心菱形表示松散的可有可无的组合关系,也叫聚集。
14.2 开放与封闭原则
程序的设计应该对修改是封闭的,对扩展是开放的。
14.3 多用组合少用继承
使用组合可以让系统有更大的弹性,不仅可以将算法封装成类,还可以在运行时动态地改变对象的行为。
14.4 面向接口编程
上层模块通常是包含抽象方法的抽象类,而继承他们的子类要提供这些方法的实现。通常这些子类叫做对接口的实现。
第15章 创建型模式
15.1工厂模式:构造不同种类的面条
15.1.1简单工厂模式
简单工厂模式:对象的产生细节由一个特定的类负责,并且该类中包含了必要的逻辑判断以产生不同的对象。
15.1.2工厂模式
工厂模式的关键在于具体的对象的创建时机推迟到工厂子类中完成。不希望高层的模块和具体的硬件细节打交道,所以把产生这个对象的工作交给工厂模式去完成。
15.1.3Factory模式总结
定义一个创建对象的接口,让子类决定实例化哪个类。factory模式使一个类的实例化延迟到其子类。
15.1.4如何进一步去掉switch/if语句
对于缺省的Constructor可以:
function obj=createObj(classname)
obj=eval(classname);
test:createObj(‘Sub1’);
否则对于如下的Constructor:
classdef Sub1&handle
properties
function obi=Sub1(var)
可以使用strcat构造要执行的命令的字符,然后再用eval函数执行命令。
classname=’Sub1’;
cmd=strcat(classname,’(’,’10’,’)’);
obj=eval(cmd);
或者使用str2func函数,从classname处获得类的构造函数的句柄,然后像正常使用构造函数那样调用该函数句柄。
classname=’Sub1’;
ConstructHandle=str2func(classname);
obj=ConstructHandle(3);
15.1.5 抽象工厂
最后的产品是各种面条的聚集。
15.1.6 AbstractFactory模式总结
提供一个创建一系列相关或者相互依赖的对象的接口,而无需指定它们具体的类。
类之间的协作
在运行时,client将负责创建一个ConcreteFactory类的实例,这个具体的工厂具有创建不同对象的代码。Client可以更换具体的工厂以得到不同的具体的产品。
何时使用AbstractFactory模式
当一个系统要独立于它的产品创建、组合、表示时。
当一个系统需要多个产品系列中的一个来配置时。
当需要强调一系列相关产品的设计时,以便进行联合调用。
15.2 单例模式:给工程计算添加一个LOG文件
15.2.1 如何控制对象的数量
MATLAB工程科学计算时,在过程中输出一些结果,用来调试程序。一般记录中间结果的文件叫做LOG。在程序运行期间,都能往LOG中写入数据,并且程序运行期间有且只有一个LOG。
单例Singleton模式:该模式用来控制一个类所产生的对象的数量。
classdef MyClass&handle
methods(Access=private)%私有构造函数
function obj=MyClass()
disp('constructor called');
methods(Static)
function obj=getInstance()%静态接口方法
persistent localObj
if isempty(localObj)||~isvalid(localObj)%如果localObj不存在则创建
localObj=MyClass();
obj=localO%如果localObj已存在则返回
obj1=MyClass.getInstance();
obj2=MyClass.getInstance();
obj3=MyClass.getInstance();
这是一个Handle类,所以构造出来的obj1,obj2,obj3实际指向同一个实例。
15.2.2 应用:如何包装一个对象供全局使用
classdef LogClass&handle
properties
methods(Access=private)%私有构造函数
function obj=LogClass()%打开文件
obj.FID=fopen('logfile.txt','a');
function delete(obj)%关闭文件
fclose(obj.FID);
function print(obj,string)
fprintf(obj.FID,string);
methods(Static)%控制外部访问
function obj=getInstance()%静态接口方法
persistent localObj
if isempty(localObj)||~isvalid(localObj)%如果localObj不存在则创建
localObj=LogClass();
obj=localO%如果localObj已存在则返回
15.3 建造者模式:如何用MATLAB构造一辆自行车
15.3.1 问题的提出
15.3.2 应用:Builder模式为大规模计算做准备工作
15.3.3Builder模式总结
将一个复杂对象的构建与它的表示方法分离,使得同样的构建过程可以创建不同的表示。
Builder模式结构
Director、Builder、ConcreteBuilder、Product、Part
类之间的协作
Client(外部程序)负责构造Director对象,并且设定该Director所要指导的具体Builder。
Director拥有Builder对象,并且可以替换。
Builder拥有product对象,Product对象由parts对象组成
构造产品的请求发自于Director,Builder接到请求之后按照Director所指导的顺序把parts对象添加到产品中去
何时使用Builder
当构造过程中允许被构造的对象有不同的表示时。
当创建复杂对象的算法,要独立于该地对象的装配方式时。
第16章 构造型模式
16.1 装饰者模式:动态地给对象添加额外的职责
16.1.1 装饰者模式的引入
16.1.2 面馆菜单代码
这种设计对修改是封闭的,还支持多次装饰,对扩展是开放的。
16.1.3 装饰者模式总结
动态地给对象添加一些额外的职责,就增加功能来说,Decorator模式相比生成子类更为灵活,Decorator模式也叫做包装器。
装饰者模式结构
Component、ConcreteComp1、ConcreteComp2、Decorator、ConcreteDeco1、ConcreteDeco2
类之间的协作
Concrete Component和Concrete Decorator都有相同的基类,并且Decorator基类中的compHandle被用来指向
何时使用Decorator模式
Decorator模式可以避免通过创建子类来扩展类的功能,Decorator是以动态的方式给单个对象添加新的功能。想要扩展类,又想避免子类数量爆炸时,可以考虑使用Decorator模式。
第17章 行为模式
17.1 观察者模式:用MATLAB实现观察者模式
17.1.1 发布和订阅的基本模型
17.1.2 订阅者查询发布者的状态
17.1.3 把发布者和订阅者抽象出来
17.1.4 Observer模式总结
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知,并且自动被更新。
Subject、ConcreteSubject、Observer、ConcreteObserver
类之间的协作
具体的观察者向ConcreteSubject对象发出订阅的请求,该ConcreteSubject对象把具体观察者加到其内部的一个列表中。
当ConcreteSubject内部发生改变,需要通知其观察者时,它将遍历其内部的观察者的列表,依次调用这些观察者的update方法。
观察者得到更新的通知,它可以向ConcreteSubject对象提出查询请求。
17.2 策略模式:分离图像数据和图像处理算法
17.2.1 问题的提出
17.2.2 应用:更复杂的分离数据和算法的例子
17.2.3 Strategy模式总结
Context、Strategy、StrategyA、StrategyB、StrategyC
类之间的协作
在Context对象中存放数据,而Strategy对象中存放算法,Context对象可以选择所需要的算法。
Context对象把来自外界的计算请求转交给Strategy对象。
转交请求是,Context把自己作为一个参数传递给Strategy对象,以提供Strategy对象计算所需要的数据。
Strategy模式何时使用
Strategy模式是用来封装算法的,在实践中,可以用来封装几乎任何类型的规则。如果在分析过程中,需要在不同的情况下应用不同的算法,就可以考虑使用Strategy模式来处理问题。
17.3 遍历者模式:工程科学计算中如何遍历大量数据
17.3.1 问题的提出
files=dir(c:\datafolder);
files=files(cell2mat({files(:).isdir})~=1);%去除文件夹中的目录
for i=1:length(files)
inputname=file(i).
imgObj=Image(inputname);
imgObj.doMethod();
17.3.2 聚集(Aggregator)和遍历者(Iterator)
17.3.3 Iterator模式总结
Iterator(内部)的意图是用一种方法顺序去访问一个聚集对象中的各个元素,而又不用暴露对象的内部显示。
Iterator模式结构
Aggregator、ConcreteAggregator1、ConcreteAggregator2、Iterator、ConcreteIterator1、ConcreteIterator2
类之间的协作
因为遍历的方式和Aggregator自身的内部情况有关。只有Aggregator才有足够的信息来告诉外部类该如何遍历自己,所以具体的Aggregator负责产生具体的Iterator。
具体的Iterator类将拥有Aggregator的Handle用来从集合中取元素
两个Base类用来提供接口,规定具体的Aggregator和具体的Iterator应该提供何种方法,以及方法的signature应该是怎么样的
ConcreteIterator提供不同的遍历方式,比如ConcreteIterator1提供从前往后的遍历,而第二个则是随机遍历。
17.4 状态模式:用MATLAB模拟自动贩卖机
17.4.1 使用if语句的自动贩卖机
17.4.2 使用StatePattern的自动贩卖机
17.4.3 State模式总结
状态模式:允许对象修改内部状态是改变它的行为,对象看起来好像是修改了它的类。
State模式的结构
Context、State、ConcreteState1、ConcreteState2
类之间的协作
对于来自外界的和自身状态相关的请求,Context对象将这些请求委托给ConcreteState对象处理。
ConcreteStata对象可以访问Context对象,也可以改变Context对象的内部状态。这就要求:在request方法中,Context对象必须把自己作为一个参数传递给ConcreteState对象。
使用Context类的client不需要和State的对象打交道。
何时使用State模式
当对象的行为取决于它的状态,并且该对象在运行时会改变状态。也就是说对象的行为会在运行时改变,可以考虑使用State模式。
当一个操作中含有庞大的多分支条件语句,而且这些分支语句依赖于对象的状态时,可以考虑使用State模式将每个条件分支放入一个独立的类中,而对象的状态对应于拥有一个状态类对象。
17.5 模板模式:下面条和煮水饺有什么共同之处
17.5.1 抽象下面条和煮水饺的过程
17.5.2 应用:把策略和模板模式结合起来
17.5.3 Template模式总结
模板方法模式:定义一个操作中的算法的骨架,将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可以重新定义该算法的某些特殊的步骤。
Template模式的结构
AbstractClass、ConcreteClass1、ConcreteClass2。Template模式中,含有反向控制的结构,因为通常是子类调用父类的操作,而在这个模式里,却是父类调用子类。这种结构也被叫做好莱坞模式。
17.6 备忘录模式:实现GUI的UNDO功能
17.6.1如何记录对象的内部状态
17.6.2如何利用备忘录模式实现GUI的do和undo操作
17.6.3Memento模式总结
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样,以后可以将该对象复原到原先的状态。
memento模式结构
类之间的协作
Originator是拥有状态的对象,外部的命令向originator发出一个请求,要求保存备忘录。
originator把自身状态数据封装到一个memento对象中,并且提交给caretaker保存。
只有Originator知道该如何利用Memento对象中的数据,Caretaker的工作仅仅是保存各个Memento对象,不能对备忘录的内容进行操作。
我的博客园:http://www.cnblogs.com/hainingwyx/
写在之前 因为简书字数限制,完整版地址:https://www.zybuluo.com/hainingwyx/note/609905如有错误,烦请指正! 第1章 面向过程和面向对象程序设计 1.1 什么是面向过程的编程 定义:一种以过程为核心的编程算法,把问题的过程按照步骤...
第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型和基本包装类型 用类型的值(对象)是引用类型的-个实例。在ECMAScript中,引用类型是--种数据结构, 1 I用于将数据和功能组织在一起。它也常被称为类,...
1.1 什么是自动引用计数 概念:在 LLVM 编译器中设置 ARC(Automaitc Reference Counting) 为有效状态,就无需再次键入 retain 或
release 代码。 1.2 内存管理 / 引用计数 1.2.1 概要 引用计数就像办公室的灯...
百战程序员_ Java1573题 QQ群:034603 掌握80%年薪20万掌握50%年薪10万 全程项目穿插, 从易到难,含17个项目视频和资料持续更新,请关注www.itbaizhan.com 国内最牛七星级团队马士兵、高淇等11位十年开发经验专...
文/鬼风流 大三 我在一个三线城市上着很一般的二本 几分钟前刚从考场回来 专业课考试,近世代数 必挂无疑 八道填空题基本不会,四道名词解释只写了三道,两道小证明四道大证明,除了‘证∶’之外什么都没有写。 内心对于自己的愧疚只维持了一分钟,剩下的是自责,围着操场走了几圈,等着...
什么成就了你的现在?答案是习惯。在查尔斯.杜希格的《习惯的力量》一书中提到,习惯是由暗示——惯常行为(渴求感)——奖赏,这三部曲形成的,并储存在我们大脑中的基底核,最后形成习惯。 举个例子吧!为什么吃货特别爱吃?他们的习惯回路是这样的:看见(闻见)美味的食物(暗示)——把它...
最近入了几本新书,有一本叫《机器人间》,是一本科幻小说集。 最近的几部美剧,例如《西部世界》、《真实的人类》这些都是讲未来机器人与人类并存的场景,当然也不能忘了《黑镜》这个很有讽刺和警醒意味的系列??。加上最近人工智能很火热,多多少少,大家还是会对以后机器人大量取代人类工作...
我们国家恢复高考时我还是一名知青,奶奶病重父母让我请了假照顾她老人家。在医院奶奶的病床边我会见缝插针抽空复习一下功课准备高考,那时对大学一点都不了解,不知道大学究竟分哪些专业,当查房的医生问到你准备考什么大学呀?我就随口答到考医学院...

我要回帖

更多关于 matlab 结构体 的文章

 

随机推荐