4号时,我修改了窗口基类w_basewindow上的缩放函数,open事件,删除了一个实例变量,
然后打包了两个dll文件,这两个dll文件内包含的窗口都打不开了,程序直接死掉,其他dll内的窗口没问题。
然后,我把包含窗口基类的dll也打包,先前打包的两个dll内的窗口显示正常了,但是其他的窗口有显示不正常啦。
最后,我将基类恢复原样,然后将修改的两个dll重新打包,算问题过去啦。
所以产生了一个问题,基类的那些修改,会对子类有影响,需要子类重建,或者重新打包DLL文件。
我的理解,
1、修改基类的默认的事件应该是不影响子类的。
2、增加基类的实例变量,子类需要重建?
3、删除基类的实例变量,子类需要重建?我知道子类代码内不会自动删除,需要手动删除。
4、增加基类的函数,子类应该不用重建吧
暂时想到的,我找资料看看吧,先把问题发上来,如果有现成的解答,或者提供资料,不胜感激。
------解决方案--------------------
1、修改基类的默认的事件应该是不影响子类的。
这个在子类的事件里右键,看Extend Ancestor Script是否勾上,勾上了会有影响,没勾上就没影2、增加基类的实例变量,子类需要重建?
这个如果只是基类使用了应该不用重建
------解决方案--------------------
你改了基类,整个工程需要FULL-REBUILD(当然一些时候是不需要,甚至大部份情况下不需要。但作为一种好习惯,我们的建议是,不论何时,永远都是FULL-REBUILD)
其中的情况比如(这只是一个简单的例子,实际不同的情况很多很多)
------------------------------------
1.子类(在很久以前)就加了一个实例变量
比如
long il_child
2.父类在这之后,也加了一个实例变量
比如
string is_base (你打开子类,会看到一个is_base的属性)
//同一个东西,父类就有的,它就显示为属性(Propertie),到自己这一层才有的,它就显示为实例变量(Instance Variable)
这两个东西,就PB内部而言,完全是相同的东西
------------------------------------
按我们一般所能看到的公开的文档,父类加了这个实例变量没有影响到子类。
但实际上是有。
(一些时候,只是一些时候,不是全部时候)
PB并不是用实例变量名指代这个变量,而是用序号
比如 "第100个实例变量"
那好了,最开始,父类有99个实例变量或属性
子类加的"long il_child"是第100个
父类后来加"string is_base",它也是第100个
到这里,运行时会有问题。
如果你FULL-REBUILD,PB才会帮你把"long il_child"改为第101个.
------解决方案--------------------
+1
------解决方案--------------------
建议这么处理,供参考
修改基类,full rebuild,至于发布哪些dll,根据修改基类内容。
1、修改基类的默认的事件应该是不影响子类的。
答:这个会有影响,尤其是基类本来没有代码,增加了代码,肯定会影响子类的。
2、增加基类的实例变量,子类需要重建?
答:这个对子类没有影响
3、删除基类的实例变量,子类需要重建?我知道子类代码内不会自动删除,需要手动删除。
答:这个肯定有影响,子类需要重建
4、增加基类的函数,子类应该不用重建吧
答:这个对子类没有影响
对子类没有影响的,你可以只发布基类,对子类有影响的,你要发布所有。
------解决方案--------------------
版主说的是常见情况,但实际一些不常见的不在此例。
就事论事,如果减少实例变量有影响,那增加也会有影响。
因为上面说的100和101的情况。//不要问我为什么知道,我叫雷锋。这个问题,在精力/能力/时间/兴趣都是最充沛的时候,花了兄弟我超过半年的时间。说出来都是泪。
---------------------------
换成我们自己来写编译器,
假定写一个父类,它实例化的时候,占8个CHAR的内存。操作系统(实际到PB,你可以认为是虚拟机)会为它HOLD住8个字节的内存。
//留意,同一个类的多个实例,比如"my_userobject_class luo_temp[100]",共享变量和函数/事件执行体只使用一个副本(我们指的是一般按普遍编译原理开发的编译器,你硬要开100个副本不在此例)。8个CHAR我们只算实例变量。
那子类新的实例变量,会从第9个字节开始。
---------------------------
父类加一个实例变量的时候,它也是从第9位开始的。并且原理上,它不会通知所有的子类(假如你不FULL-REBUILD的话),"你之前以为我长了两只手,现在老子长三只了"。//因为它不知道谁引用了它作为祖先。曾孙知道谁是它的曾祖父,但曾祖父不知道他有几个曾孙。
当然,这些问题,技术上是有办法解决的。PB也解决了其中的大部份。(这个就不举例子了,因为多少算商业秘密。但我敢保证,SYBASE一定/*或至少在某些PB的版本上*/没有解决一些问题)
但很不幸,其中的一小部分并没有解决。//不要问我为什么知道,我叫雷锋。我家里有三部电脑,24小时满CPU运行跑了几年,大部分的工作,是为了找到这些问题,让我可以解决或至少是知道它们哪里。
---------------------------
写这么多,其实只是说,反正100和101这个问题是存在的。
具体例子在
http://www.shuct.net/shudl.asp?id=20091227
测试一下运行结果,或用反编译器(我不说用哪个编译器可以看出结果/*有一些看不出的*/,自己找。),分析其中的两个EXE,因为父类变了,会导致子类运行结果不同。
//不一定需要看清楚原因或原理,只是为了向您说明,100/101的问题是存在的。
类似的现象其实还有,并且不少。
---------------------------
写这么多,是为了说明。
重要,
我们的建议是,发布程序前,FULL-REBUILD,并一起发布。不然可能有问题,甚至其中的一些问题,SYBASE(或现在是SAP),都不一定知道。
------解决方案--------------------
父类增加变量要看类型的
不是说子类就一定要在变量定义下标中被动增加1
kenshu你只考虑到一层继承而已,多层继承中你想过没有?
要区分private,protected,privatewrite等
同时,如果只是单纯的增加一个public变量,任何子类都没有使用这个变量(打开子类源文件,没有这个变量),那么也不需要fullbuild的
最后,你们大多都使用pb自己的编译器吧,我不是,我用的是powergen,powergen处理这个聪明多了,并且powergen可以用高版本的编译器直接编译低版本的pb代码,而不用去升级
------解决方案--------------------
1."kenshu你只考虑到一层继承而已,多层继承中你想过没有?"
我想过,
比如
super0->super1->child