如何获取对象变量所占字节数?【100分】

时间:2023-01-10 08:02:24
我们定义了一个对象变量
 比如
 dim obj  as object 
 然后
 set obj=creatobject("test.test")

 然后做一些操作,插入数据,赋值之类的

 接下来,如何获取这个obj到底占用了多少字节的内存呢?

39 个解决方案

#1


Option Explicit
Dim mXlsApp As Excel.Application '应用
Dim mXlsBook As Excel.Workbook '工作薄
Dim mXlsSheet As Excel.Worksheet '工作表

Private Sub Command1_Click()
  Set mXlsApp = New Excel.Application
  Set mXlsBook = mXlsApp.Workbooks.Open("c:\book1.xls")
  Set mXlsSheet = mXlsBook.Worksheets(1)
  
   Debug.Print LenB(mXlsApp)'我的电脑显示是30个字节  
' 以下代码读取Excel中图表到图片框
  mXlsSheet.ChartObjects(1).Chart.CopyPicture  '读取图表到剪贴板
  Picture1.Picture = Clipboard.GetData '粘贴数据到图片框
  Clipboard.Clear '清除剪贴板数据
  mXlsBook.Close
  mXlsApp.Quit
  Set mXlsSheet = Nothing
  Set mXlsBook = Nothing
  Set mXlsApp = Nothing
End Sub

#2


LenB可行

#3



Option Explicit

Private Sub Command1_Click()
    Dim obj     As Object
    
    Set obj = CreateObject("adodb.recordset")
    
    ''Debug.Print obj Is Nothing
    
    Debug.Print LenB(obj)
    
    Set obj = Nothing
    
End Sub



提示,错误的参数或者无效的属性值

#4


Object永远为4字节,保存的是实际对象的地址,lenB(obj)可得到对象的结构大小,从技术上说,系统是无法确定一个对象实际所占的字节数的,要得到实际大小,只能依靠对象本身

#5


要得到一个对象及对象本身的数据占用多少内存空间,
只能该对象自己来处理这个问题(增加一个反回空间占用量的函数)


你别指望用 Len() 或 LenB() 来得到这个数据。这是不可能的。

#6


引用 5 楼  的回复:
要得到一个对象及对象本身的数据占用多少内存空间,
只能该对象自己来处理这个问题(增加一个反回空间占用量的函数)


你别指望用 Len() 或 LenB() 来得到这个数据。这是不可能的。


我需要知道的,正好又不是自己可以控制的对象,比如recordset之类的

这个或许是有办法的,只是我不知道而已

#7


引用 6 楼  的回复:
引用 5 楼 的回复:

要得到一个对象及对象本身的数据占用多少内存空间,
只能该对象自己来处理这个问题(增加一个反回空间占用量的函数)


你别指望用 Len() 或 LenB() 来得到这个数据。这是不可能的。


我需要知道的,正好又不是自己可以控制的对象,比如recordset之类的

这个或许是有办法的,只是我不知道而已

别作无用功,为什么?指针!

#8


引用 7 楼  的回复:
引用 6 楼  的回复:
引用 5 楼 的回复:

要得到一个对象及对象本身的数据占用多少内存空间,
只能该对象自己来处理这个问题(增加一个反回空间占用量的函数)


你别指望用 Len() 或 LenB() 来得到这个数据。这是不可能的。


我需要知道的,正好又不是自己可以控制的对象,比如recordset之类的

这个或许是有办法的,只是我不知道而已

别作无用……


这是需求,

#9



Option Explicit

Private Sub Command1_Click()
    Dim objP As Variant
    objP = "adkd"
    Debug.Print LenB(objP)
    Set objP = Nothing
    Debug.Print LenB(objP)
End Sub


对于Nothing 的对象,会报错。

#10


这是做不到的。

比如你是老板,雇了一名员工,虽然你发工资给该员工,也无法确切知道该员工的个人资产是多少。
该员工有自己的房产、现金,还有欠别人的钱,也有借给别人的钱,许多都属于隐私,你无法知道的。

同样一个被你调用的对象,你也无法知道它的内存耗用,光看进程的内存增长也没用,有些增长的内存并不属于该对象。

#11


这主要和编译器和对象的类型有关
对于一个简单的vb类,我倒是可以数出来具体用了多少内存,但意义不大
你的问题其实是vb的根本症结,如果这个长度知道了,也就能实现vb的对象继承了

#12


继承和内存没关系。
VB 和 VC 都用对象指针,却在继承的支持上有所不同。

只要用指针的语言(包括 .Net),就不需要关心对象 精确的内存占用。
只需要按照数据量估算一下 大概的内存耗用,然后选择恰当的数据结构就可以了。

#13


继承需要复制副本,复制副本即复制内存,复制内存即需要复制长度及起始地址或称指针

单纯的指针作用,是引用,而且真正意义上的继承,vb中惯用的方法就是引用,因为单纯的vb没有直接的继承方法,com对象包括继承,vb的对象则不可实现继承,所以有人说vb非面向对象的编程语言

对于对象的继承,估算?。。。。

#14


和继承这些应该没多大关系,C++可继承,但C++也无法计算一个对象所占内存,根本原因在于,机器无法区分对象的一个long成员到底是一个数值还是一个指向其它结构的指针,纵算做到了区分,那这个指针指向的结构的大小怎么算?这个结构中又有指向其它结构的指针,还有这些二级、三级指针。。。可能又指向上层结构,在一个稍有规模的系统中,所有对象岂不是构成一张巨大的网图?光遍历这张图现有机器都够呛了,还有时间做其它事?

#15


简单来说, 继承就是复制一个 实例化 对象A 的副本
复制副本就必然要复制内存, 如果没有指针(复制的起始位置) 和 长度(对象数据) 怎么实现复制?

一个对象, 一般就说类这个东西, 到底是什么样? 他的数据不是抽象的放在内存中哪哪都是一堆,或者一坨东西....

他是有组织, 有纪律, 有文化, 有素质的紧密且连续顺序的排列在一个堆上, vb中,一个不含任何成员或数据的对象至少包括28 bytes数据, 多一个 private 变量则多 4 字节,一个public 类型变量则至少是4字节,通常是 8字节, 对象的数据可以想象为一个结构体, 一个容纳了全部对象成员的结构, 继承或者说复制这个对象, 就是复制这个结构, 还有一些基础知识不再解释... 

以上内容, 可供观赏...

#16


有组织, 有纪律, 有文化, 有素质是真的,紧密且连续顺序的排列就不一定了,最简单的指针链表还真就有可能这是一堆,哪是一坨;如果不知道节点数目或者结束标志,根本无法计算这个链表的长度,而这两点对象外的东西是很难知道的;
不是对象所占内存不能精确计算,而是实现的机制上不太可能由对象外的东西计算;
复制副本根本不是个问题,只要每个对象都能遵守一定规则,对外提供计算长度、复制自身等方法即可,比如一些常见的C++或C#对象的Clone,Ado对象的Clone
最后顺便,VB6其实也有继承,只不过不是基于类,而是基于接口而己

#17


...............

书中自有颜如玉... 书中自有黄金屋... 多看看书... 总是好的... 

#18


基于类的继承其实是由编译器决定的,编译器可以在 编译时计算父类和子类的实例需要多少内存
(仅仅是引用计数、VTable 指针、模块级变量 自身的内存,至于字符串、数组、类等变量 数据所占的内存是不算在内的),
类实例的大小不是在 运行时计算的!

熟读二十四史并不有助与编程,不同的问题还是要看不同的书。

#19




我只是没兴趣把话说的那么明白... 啰啰嗦嗦一大堆...

首先,基本上都可以在编译时确定的,而不是什么大约多少。。。
之后再看书,然后贴上来,更不能说明问题
看什么书都行,关键是看全、看对,别只看一点

vtable 记录着一切,就算不能复制一切,也能复制指针,形成带数据引用的继承; 而且叫vtable也不靠谱,并非所有编译器都叫他vtable,所以临时看一点,实在过分

每个编译器对对象的处理方式都不同,对象的定义本身是广泛的为方便编程的,不同的定义的编译器所构建的不同对象编译方式都可以写本书来描述

某些楼层的说法,稍稍适用于VC++,对于VB6的对象则不可同日而语; 
24史没看过,1史都没看过,3国比较喜欢,3字经也研究过,不过我倒是觉得语文老师说多看书是最正确的,也许红楼梦中就写着只顾着泡妞而不讲究方法,也是不行的

正是因为类的继承不是在运行时确定所需的内存大小,而是在编译时就确定了,这个确定过程是基于字符编译的宏来完成的

举个例子,open 语句将一个结构写入文件时,如果结构包含数组,则可以将结构内容全部写入,而不是把结构中的数组的地址写下去,这个例子可能不够恰当,因为这是COM对象特性,对于晚期实现的动态内容,COM对象在编译前和编译后对有效数据都是区别对待的,但例子也可以说明,编译器也好,对象也好,是“智能的(具体内容不在阐述)”,而非将一个4字节数据简单的看成一个long值而已,由此来说明数组之类的东西在复制时的方式

24史中如果包括怎样消灭银河系,那不妨多看;就算是金瓶梅也有很多可取之处。。。

说一点我对看书的经验吧,我看书不象别人,喜欢把书中的内容倒背如流或是练就一手copy大法的到处张贴,我比较喜欢理解着看,印证着看,因为更多时候我是带着问题去看
读的多了,理解深了,可能是摸到了一些本质,对问题的看法也就不同了,随意的就把正确的内容按照自己的理解告诉别人,别人更多的是不理解,我认为:无所谓。。。因为他说的,我理解,而且知道他在开玩笑

#20


你看书如何如何。。。并不能说明别人就不是如何如何。。。这是最基本的逻辑。。。现代计算机也是基于逻辑的哦

随意的就把 正确的内容按照自己的理解告诉别人,别人更多的是不理解,我认为:无所谓。。。……怎么就是 正确的内容,爱因斯坦的最大贡献不是原子弹,而是告诉人们没有绝对的正确,只有局部的正确

某些楼层的说法,稍稍适用于VC++,对于VB6的对象则不可同日而语;。。。怎么看这句话都带有强烈的中国特色

能扯是好的,但无助于问题的解决!

#21


能扯确实是好的,连基本概念都不懂,就不要扯了

#22


不要把 VB 和 VC 看得有多么的不同。
到 Visual Studio 6 的目录下搜一下,可以看到两者用了同样的 LINK.EXE。

语言其实就是描述方式不同,底层没什么区别。
对于 COM 对象
VB 基于实现的继承其实就是限定不同的类之间 VTable 完全独立。
VC 基于类的继承其实就是可以在父子类之间复制或直接调用 VTable 内的函数指针。
一切由编译器决定,而无论 VB 还是 VC 开发的 COM 对象,在外部表现和底层结构上没有特殊的区别。

#23


继承为什么要复制基类呀,那不非要去确定基类需要多少内存?基类的基类需要多少内存?基类里要是用了动态申请内存的,还不疯了?

一个对象在内存里面,数据是属于每个对象自己的,数据里面肯定有个指针指向基类,而不是复制个基类到这个对象来.
对象的方法是公用的,就是程序代码在整个内存中只存在一份,这个类型的所有对象都共享这些程序代码.vb里面都有this,me这样的参数在程序中来区别不同对象.

#24


好吧,弄了一堆也都没了,你赢了。。。 哪跟哪啊

#25



看晕了。是教授们自己掐起来了?

#26


*为家庭分房,规定每个子女一间房:
某家三个儿子,于是三间房;
老大后来成家有了两个儿,于是得房两间;
多年后孙子长大成人结婚生子若干,于是又分得间若干;
。。。。如此。。。

显而易见,*不可能做到为每个家庭的成员分配相邻房间

现在*想知道这家到底分了多少房?
1、规定所有家庭成员必须向他爹申报自已所有的房间数,这样*只需找这家家长要数据即可;
2、*自已统计;

想用第2种方案,那就 必须清楚每个成员间的关系,这两点如何做到呢?
如果再允许成员可以把房间*处置,可以拆掉(销毁)、升二层(动态申请)、交换(交换指针)、馈赠和继承……
面对这些,有谁还想自己去统计呢?

所以方案2只是理论可行,实际上有谁会这样做呢?

#27


引用 26 楼  的回复:
*为家庭分房,规定每个子女一间房:
某家三个儿子,于是三间房;
老大后来成家有了两个儿,于是得房两间;
多年后孙子长大成人结婚生子若干,于是又分得间若干;
。。。。如此。。。

显而易见,*不可能做到为每个家庭的成员分配相邻房间

现在*想知道这家到底分了多少房?
1、规定所有家庭成员必须向他爹申报自已所有的房间数,这样*只需找这家家长要数据即可;
2、*自已统计;……

派生类能知道基类的内存数?或者基类知道派生类的内存数?
例子挺好,却不完美.

那当爹的遇到*分房子,会说:这是我的3个孩子得地址,你去统计他们吧...

#28


1、类是类,对象是对象,两者不可以混淆的,类相当于块模板,因此可认为不占据运行内存,对象才真正占据内存,好比说“美国人”占领伊拉克,“美国人”这个类去了吗?事实是一些叫做John、Jack的,有“美国人”这个特征的人(对象)占的。


...会说:这是我的3个孩子得地址,你去统计他们吧...

不错,和第一种一样,即都得基于对象的“自觉性”,得靠对象本身

#29


该回复于2012-09-03 10:46:15被版主删除

#30


说到底还是一个指针

#31


如何获取对象变量所占字节数?【100分】如何获取对象变量所占字节数?【100分】

#32


哈,真够热闹的,不过后面好象跑偏了点 如何获取对象变量所占字节数?【100分】

我觉得要计算出一个对象所占的精确内存应该是有办法的,只是没什么很大的意义而已.

毕竟所有的内存申请释放都是VB完成的,它自己要是搞不清楚那还怎么搞...

上面有个例子,就是向文件写入自定义类型的变量,OPEN与PUT及GET都能智能地将不包含对象引用的自定义类型进行文件IO,这点在做配置文件时比较方便.

不过不能保存实例化的对象数据,也不能进行对象继承,我估计更多还是基于定位的考虑吧,非不能也,乃不为也.....

扔砖完毕,继续看玉....

#33


没玉,我是来砌砖的!

#34


仅供参考
MSDN98中的例子walker又名pwalk。完整列出指定进程的内存使用情况,显示进程地址空间内容,装载哪些DLL,代码、数据、堆栈段分配在何处,可以用来检测内存泄漏,监测内存使用。 
http://download.csdn.net/detail/zhao4zhong1/3667896

#35


钓鱼岛这么紧张,你们还有心思在这儿争论?

#36


引用 32 楼  的回复:


乐色马

open,put,get 所指的意义是,对于vb预定义的大多数变量类型的存取,不是简单的字节读写
不是简单的内存copy,由此说明vb类副本的可行性
vb的不行完全在于编译器根本不处理这些,vb和vc的编译器有着非常大的区别
link.exe 一样编译方法,方式,内容就一样? 各位看官知不知道 link.exe 仅仅是连接器,他把编译器编译好了的模块文件组合成一个 exe而已? 只是vc .net 版本后新增了link时代码的优化

我再明确下,我的观点:
   可以,但并非完全可以;之前已经说过,编译器不支持,自己折腾来折腾去的总也好不到哪去,因为这需要从根上解决

 再举个例子:
      vb Class1's vtable:

    memory   | sub names & type
     +0          function:iunknow
     +4          function:addref               
     +.          function:...
     +24         function:------ 前 28字节重型接口略
     +32         function:mysub1
     +36         function:myproperty1
     +40         function:myproperty1
     +44         function:myPublicVar1
     +48         function:myxxx 
     +..         function:------ N 个 * 4 字节公用: 属性,方法,变量略
     +.. +4      function:mysub1
     +.. +8      function:myproperty1
     +.. +12     function:myproperty1
     +.. +16     function:myfPrivateVar1
     +.. +20     function:myxxx 
     +.. +.      function:------ N 个 * 4 字节私有: 属性,方法,变量略

以上为某 class 类型vb对象在内存中的详细map
帖子内容,全部是自己手动写上来的, 如果哪弄错了, 凑合看吧... 应该不难理解
这就是一个完整的 vtable map
形式上看就是个 结构类型
公共部分不说了,一般来讲如果要复制副本,直接copy即可,因为大部分方法也好,变量也好,都是以地址方式保存的,因为要支持晚期调用
妨碍我们进行复制的就是私有的部分,私有部分内容只有编译器在编译时清楚到底放进去了多少内容,这和你声明的类局部变量数量,私有函数,方法,过程,属性有关 

在表的私有内容部分,如果有 as long 类型, 直接复制即可, 你说你存的是一个新申请的内存指针,但如果需要进行副本复制,这里只复制 long 数据,其余不理,道理大家该理解。诸如此类,预定义类型,如 integer,byte,single,double等通通如此

特别一些的是 string,class,array (还有更多);这些内容的复制并非无法实现,最简单的是 a =b  即复制了一个新的,但私有部分的内容是隐蔽的,编译器从根本上不提供这项功能
如果还是需要复制副本的功能,就可以用copymemory的方法实现了,知道了这个表长度直接复制即可

我做了一个最简单的: 复制对象
           演示代码: http://files.cnblogs.com/pctgl/copy2new.rar

                内有详细注释, 很简单

提示: 以上代码仅做演示一途, 绝非万全之策, 切不可用于正式项目,但也算较为安全,不会轻易弄挂你的程序


以后就是这帖的看客了, 各位有想多研究这方面的,不如来我的blog一起研究 pctgl.cnblogs.com

#37


话题可能越扯越远了,但真心觉得这问题和编绎器扯不上关系!

操作系统关心窗口,进程,线程等等对象,因此从操作系统的角度说,窗口,进程等对象所占内存是可精确计算的,因为操作系统了解它们的结构;但要知道一个用户自定义对象所占内存,操作系统恐怕就无能为力了,因为这些对象并不是直接向操作系统申请,而是由进程等对象代申请,操作系统的帐本上记的是进程的名字,而不是用户自定义对象的名字--当然,如果操作系统愿意为每一个申请内存的对象建帐本就另说!

延伸一点说,进程是否又愿意为进程内的每一个对象建个帐本呢?

从数学的角度说, 如果你要了解更详细的收支情况,那你就得有更详细的明细记录表.

为什么要和继承扯上关系统呢?继承是针对类来说的,而不是对象。我们说某类继承自某类,而不是说某对象继承自某对象。

关于复制副本,那要看你怎样理解“副本”这个东西了,B与A的指针成员都指向同一个地方,我们可认为B是A的副本,但从另一个角度说,B与A的指针成员虽然没指向同一个地方,但它们指向的地方的数据都是完全相同的,难道不认为B也是A的副本吗?就像a=1,b=a,虽然a,b地址不一样,但a,b的数据却是一样的。

copymemory只能得到第一种副本,并且算不上真正的副本,修改一下A的指针成员指向的数据,再看看B就知道了。在同一进程内还好,如果copymemory跨进程、跨机器的对象,恐怕可能出现的就是“该内存为XXX”了

关于a=b复制对象,如果知道“重载运算符”就容易多了,可惜,VB6这东西没有“重载”。。。

扯远了,钓鱼岛都这么紧张了,还。。。楼主咋不结贴?虽有不同看法,不过对你的问题意见还是一致的。

#38


如何获取对象变量所占字节数?【100分】好吧,结扎!

#39


看过代码吗,看懂了吗

#1


Option Explicit
Dim mXlsApp As Excel.Application '应用
Dim mXlsBook As Excel.Workbook '工作薄
Dim mXlsSheet As Excel.Worksheet '工作表

Private Sub Command1_Click()
  Set mXlsApp = New Excel.Application
  Set mXlsBook = mXlsApp.Workbooks.Open("c:\book1.xls")
  Set mXlsSheet = mXlsBook.Worksheets(1)
  
   Debug.Print LenB(mXlsApp)'我的电脑显示是30个字节  
' 以下代码读取Excel中图表到图片框
  mXlsSheet.ChartObjects(1).Chart.CopyPicture  '读取图表到剪贴板
  Picture1.Picture = Clipboard.GetData '粘贴数据到图片框
  Clipboard.Clear '清除剪贴板数据
  mXlsBook.Close
  mXlsApp.Quit
  Set mXlsSheet = Nothing
  Set mXlsBook = Nothing
  Set mXlsApp = Nothing
End Sub

#2


LenB可行

#3



Option Explicit

Private Sub Command1_Click()
    Dim obj     As Object
    
    Set obj = CreateObject("adodb.recordset")
    
    ''Debug.Print obj Is Nothing
    
    Debug.Print LenB(obj)
    
    Set obj = Nothing
    
End Sub



提示,错误的参数或者无效的属性值

#4


Object永远为4字节,保存的是实际对象的地址,lenB(obj)可得到对象的结构大小,从技术上说,系统是无法确定一个对象实际所占的字节数的,要得到实际大小,只能依靠对象本身

#5


要得到一个对象及对象本身的数据占用多少内存空间,
只能该对象自己来处理这个问题(增加一个反回空间占用量的函数)


你别指望用 Len() 或 LenB() 来得到这个数据。这是不可能的。

#6


引用 5 楼  的回复:
要得到一个对象及对象本身的数据占用多少内存空间,
只能该对象自己来处理这个问题(增加一个反回空间占用量的函数)


你别指望用 Len() 或 LenB() 来得到这个数据。这是不可能的。


我需要知道的,正好又不是自己可以控制的对象,比如recordset之类的

这个或许是有办法的,只是我不知道而已

#7


引用 6 楼  的回复:
引用 5 楼 的回复:

要得到一个对象及对象本身的数据占用多少内存空间,
只能该对象自己来处理这个问题(增加一个反回空间占用量的函数)


你别指望用 Len() 或 LenB() 来得到这个数据。这是不可能的。


我需要知道的,正好又不是自己可以控制的对象,比如recordset之类的

这个或许是有办法的,只是我不知道而已

别作无用功,为什么?指针!

#8


引用 7 楼  的回复:
引用 6 楼  的回复:
引用 5 楼 的回复:

要得到一个对象及对象本身的数据占用多少内存空间,
只能该对象自己来处理这个问题(增加一个反回空间占用量的函数)


你别指望用 Len() 或 LenB() 来得到这个数据。这是不可能的。


我需要知道的,正好又不是自己可以控制的对象,比如recordset之类的

这个或许是有办法的,只是我不知道而已

别作无用……


这是需求,

#9



Option Explicit

Private Sub Command1_Click()
    Dim objP As Variant
    objP = "adkd"
    Debug.Print LenB(objP)
    Set objP = Nothing
    Debug.Print LenB(objP)
End Sub


对于Nothing 的对象,会报错。

#10


这是做不到的。

比如你是老板,雇了一名员工,虽然你发工资给该员工,也无法确切知道该员工的个人资产是多少。
该员工有自己的房产、现金,还有欠别人的钱,也有借给别人的钱,许多都属于隐私,你无法知道的。

同样一个被你调用的对象,你也无法知道它的内存耗用,光看进程的内存增长也没用,有些增长的内存并不属于该对象。

#11


这主要和编译器和对象的类型有关
对于一个简单的vb类,我倒是可以数出来具体用了多少内存,但意义不大
你的问题其实是vb的根本症结,如果这个长度知道了,也就能实现vb的对象继承了

#12


继承和内存没关系。
VB 和 VC 都用对象指针,却在继承的支持上有所不同。

只要用指针的语言(包括 .Net),就不需要关心对象 精确的内存占用。
只需要按照数据量估算一下 大概的内存耗用,然后选择恰当的数据结构就可以了。

#13


继承需要复制副本,复制副本即复制内存,复制内存即需要复制长度及起始地址或称指针

单纯的指针作用,是引用,而且真正意义上的继承,vb中惯用的方法就是引用,因为单纯的vb没有直接的继承方法,com对象包括继承,vb的对象则不可实现继承,所以有人说vb非面向对象的编程语言

对于对象的继承,估算?。。。。

#14


和继承这些应该没多大关系,C++可继承,但C++也无法计算一个对象所占内存,根本原因在于,机器无法区分对象的一个long成员到底是一个数值还是一个指向其它结构的指针,纵算做到了区分,那这个指针指向的结构的大小怎么算?这个结构中又有指向其它结构的指针,还有这些二级、三级指针。。。可能又指向上层结构,在一个稍有规模的系统中,所有对象岂不是构成一张巨大的网图?光遍历这张图现有机器都够呛了,还有时间做其它事?

#15


简单来说, 继承就是复制一个 实例化 对象A 的副本
复制副本就必然要复制内存, 如果没有指针(复制的起始位置) 和 长度(对象数据) 怎么实现复制?

一个对象, 一般就说类这个东西, 到底是什么样? 他的数据不是抽象的放在内存中哪哪都是一堆,或者一坨东西....

他是有组织, 有纪律, 有文化, 有素质的紧密且连续顺序的排列在一个堆上, vb中,一个不含任何成员或数据的对象至少包括28 bytes数据, 多一个 private 变量则多 4 字节,一个public 类型变量则至少是4字节,通常是 8字节, 对象的数据可以想象为一个结构体, 一个容纳了全部对象成员的结构, 继承或者说复制这个对象, 就是复制这个结构, 还有一些基础知识不再解释... 

以上内容, 可供观赏...

#16


有组织, 有纪律, 有文化, 有素质是真的,紧密且连续顺序的排列就不一定了,最简单的指针链表还真就有可能这是一堆,哪是一坨;如果不知道节点数目或者结束标志,根本无法计算这个链表的长度,而这两点对象外的东西是很难知道的;
不是对象所占内存不能精确计算,而是实现的机制上不太可能由对象外的东西计算;
复制副本根本不是个问题,只要每个对象都能遵守一定规则,对外提供计算长度、复制自身等方法即可,比如一些常见的C++或C#对象的Clone,Ado对象的Clone
最后顺便,VB6其实也有继承,只不过不是基于类,而是基于接口而己

#17


...............

书中自有颜如玉... 书中自有黄金屋... 多看看书... 总是好的... 

#18


基于类的继承其实是由编译器决定的,编译器可以在 编译时计算父类和子类的实例需要多少内存
(仅仅是引用计数、VTable 指针、模块级变量 自身的内存,至于字符串、数组、类等变量 数据所占的内存是不算在内的),
类实例的大小不是在 运行时计算的!

熟读二十四史并不有助与编程,不同的问题还是要看不同的书。

#19




我只是没兴趣把话说的那么明白... 啰啰嗦嗦一大堆...

首先,基本上都可以在编译时确定的,而不是什么大约多少。。。
之后再看书,然后贴上来,更不能说明问题
看什么书都行,关键是看全、看对,别只看一点

vtable 记录着一切,就算不能复制一切,也能复制指针,形成带数据引用的继承; 而且叫vtable也不靠谱,并非所有编译器都叫他vtable,所以临时看一点,实在过分

每个编译器对对象的处理方式都不同,对象的定义本身是广泛的为方便编程的,不同的定义的编译器所构建的不同对象编译方式都可以写本书来描述

某些楼层的说法,稍稍适用于VC++,对于VB6的对象则不可同日而语; 
24史没看过,1史都没看过,3国比较喜欢,3字经也研究过,不过我倒是觉得语文老师说多看书是最正确的,也许红楼梦中就写着只顾着泡妞而不讲究方法,也是不行的

正是因为类的继承不是在运行时确定所需的内存大小,而是在编译时就确定了,这个确定过程是基于字符编译的宏来完成的

举个例子,open 语句将一个结构写入文件时,如果结构包含数组,则可以将结构内容全部写入,而不是把结构中的数组的地址写下去,这个例子可能不够恰当,因为这是COM对象特性,对于晚期实现的动态内容,COM对象在编译前和编译后对有效数据都是区别对待的,但例子也可以说明,编译器也好,对象也好,是“智能的(具体内容不在阐述)”,而非将一个4字节数据简单的看成一个long值而已,由此来说明数组之类的东西在复制时的方式

24史中如果包括怎样消灭银河系,那不妨多看;就算是金瓶梅也有很多可取之处。。。

说一点我对看书的经验吧,我看书不象别人,喜欢把书中的内容倒背如流或是练就一手copy大法的到处张贴,我比较喜欢理解着看,印证着看,因为更多时候我是带着问题去看
读的多了,理解深了,可能是摸到了一些本质,对问题的看法也就不同了,随意的就把正确的内容按照自己的理解告诉别人,别人更多的是不理解,我认为:无所谓。。。因为他说的,我理解,而且知道他在开玩笑

#20


你看书如何如何。。。并不能说明别人就不是如何如何。。。这是最基本的逻辑。。。现代计算机也是基于逻辑的哦

随意的就把 正确的内容按照自己的理解告诉别人,别人更多的是不理解,我认为:无所谓。。。……怎么就是 正确的内容,爱因斯坦的最大贡献不是原子弹,而是告诉人们没有绝对的正确,只有局部的正确

某些楼层的说法,稍稍适用于VC++,对于VB6的对象则不可同日而语;。。。怎么看这句话都带有强烈的中国特色

能扯是好的,但无助于问题的解决!

#21


能扯确实是好的,连基本概念都不懂,就不要扯了

#22


不要把 VB 和 VC 看得有多么的不同。
到 Visual Studio 6 的目录下搜一下,可以看到两者用了同样的 LINK.EXE。

语言其实就是描述方式不同,底层没什么区别。
对于 COM 对象
VB 基于实现的继承其实就是限定不同的类之间 VTable 完全独立。
VC 基于类的继承其实就是可以在父子类之间复制或直接调用 VTable 内的函数指针。
一切由编译器决定,而无论 VB 还是 VC 开发的 COM 对象,在外部表现和底层结构上没有特殊的区别。

#23


继承为什么要复制基类呀,那不非要去确定基类需要多少内存?基类的基类需要多少内存?基类里要是用了动态申请内存的,还不疯了?

一个对象在内存里面,数据是属于每个对象自己的,数据里面肯定有个指针指向基类,而不是复制个基类到这个对象来.
对象的方法是公用的,就是程序代码在整个内存中只存在一份,这个类型的所有对象都共享这些程序代码.vb里面都有this,me这样的参数在程序中来区别不同对象.

#24


好吧,弄了一堆也都没了,你赢了。。。 哪跟哪啊

#25



看晕了。是教授们自己掐起来了?

#26


*为家庭分房,规定每个子女一间房:
某家三个儿子,于是三间房;
老大后来成家有了两个儿,于是得房两间;
多年后孙子长大成人结婚生子若干,于是又分得间若干;
。。。。如此。。。

显而易见,*不可能做到为每个家庭的成员分配相邻房间

现在*想知道这家到底分了多少房?
1、规定所有家庭成员必须向他爹申报自已所有的房间数,这样*只需找这家家长要数据即可;
2、*自已统计;

想用第2种方案,那就 必须清楚每个成员间的关系,这两点如何做到呢?
如果再允许成员可以把房间*处置,可以拆掉(销毁)、升二层(动态申请)、交换(交换指针)、馈赠和继承……
面对这些,有谁还想自己去统计呢?

所以方案2只是理论可行,实际上有谁会这样做呢?

#27


引用 26 楼  的回复:
*为家庭分房,规定每个子女一间房:
某家三个儿子,于是三间房;
老大后来成家有了两个儿,于是得房两间;
多年后孙子长大成人结婚生子若干,于是又分得间若干;
。。。。如此。。。

显而易见,*不可能做到为每个家庭的成员分配相邻房间

现在*想知道这家到底分了多少房?
1、规定所有家庭成员必须向他爹申报自已所有的房间数,这样*只需找这家家长要数据即可;
2、*自已统计;……

派生类能知道基类的内存数?或者基类知道派生类的内存数?
例子挺好,却不完美.

那当爹的遇到*分房子,会说:这是我的3个孩子得地址,你去统计他们吧...

#28


1、类是类,对象是对象,两者不可以混淆的,类相当于块模板,因此可认为不占据运行内存,对象才真正占据内存,好比说“美国人”占领伊拉克,“美国人”这个类去了吗?事实是一些叫做John、Jack的,有“美国人”这个特征的人(对象)占的。


...会说:这是我的3个孩子得地址,你去统计他们吧...

不错,和第一种一样,即都得基于对象的“自觉性”,得靠对象本身

#29


该回复于2012-09-03 10:46:15被版主删除

#30


说到底还是一个指针

#31


如何获取对象变量所占字节数?【100分】如何获取对象变量所占字节数?【100分】

#32


哈,真够热闹的,不过后面好象跑偏了点 如何获取对象变量所占字节数?【100分】

我觉得要计算出一个对象所占的精确内存应该是有办法的,只是没什么很大的意义而已.

毕竟所有的内存申请释放都是VB完成的,它自己要是搞不清楚那还怎么搞...

上面有个例子,就是向文件写入自定义类型的变量,OPEN与PUT及GET都能智能地将不包含对象引用的自定义类型进行文件IO,这点在做配置文件时比较方便.

不过不能保存实例化的对象数据,也不能进行对象继承,我估计更多还是基于定位的考虑吧,非不能也,乃不为也.....

扔砖完毕,继续看玉....

#33


没玉,我是来砌砖的!

#34


仅供参考
MSDN98中的例子walker又名pwalk。完整列出指定进程的内存使用情况,显示进程地址空间内容,装载哪些DLL,代码、数据、堆栈段分配在何处,可以用来检测内存泄漏,监测内存使用。 
http://download.csdn.net/detail/zhao4zhong1/3667896

#35


钓鱼岛这么紧张,你们还有心思在这儿争论?

#36


引用 32 楼  的回复:


乐色马

open,put,get 所指的意义是,对于vb预定义的大多数变量类型的存取,不是简单的字节读写
不是简单的内存copy,由此说明vb类副本的可行性
vb的不行完全在于编译器根本不处理这些,vb和vc的编译器有着非常大的区别
link.exe 一样编译方法,方式,内容就一样? 各位看官知不知道 link.exe 仅仅是连接器,他把编译器编译好了的模块文件组合成一个 exe而已? 只是vc .net 版本后新增了link时代码的优化

我再明确下,我的观点:
   可以,但并非完全可以;之前已经说过,编译器不支持,自己折腾来折腾去的总也好不到哪去,因为这需要从根上解决

 再举个例子:
      vb Class1's vtable:

    memory   | sub names & type
     +0          function:iunknow
     +4          function:addref               
     +.          function:...
     +24         function:------ 前 28字节重型接口略
     +32         function:mysub1
     +36         function:myproperty1
     +40         function:myproperty1
     +44         function:myPublicVar1
     +48         function:myxxx 
     +..         function:------ N 个 * 4 字节公用: 属性,方法,变量略
     +.. +4      function:mysub1
     +.. +8      function:myproperty1
     +.. +12     function:myproperty1
     +.. +16     function:myfPrivateVar1
     +.. +20     function:myxxx 
     +.. +.      function:------ N 个 * 4 字节私有: 属性,方法,变量略

以上为某 class 类型vb对象在内存中的详细map
帖子内容,全部是自己手动写上来的, 如果哪弄错了, 凑合看吧... 应该不难理解
这就是一个完整的 vtable map
形式上看就是个 结构类型
公共部分不说了,一般来讲如果要复制副本,直接copy即可,因为大部分方法也好,变量也好,都是以地址方式保存的,因为要支持晚期调用
妨碍我们进行复制的就是私有的部分,私有部分内容只有编译器在编译时清楚到底放进去了多少内容,这和你声明的类局部变量数量,私有函数,方法,过程,属性有关 

在表的私有内容部分,如果有 as long 类型, 直接复制即可, 你说你存的是一个新申请的内存指针,但如果需要进行副本复制,这里只复制 long 数据,其余不理,道理大家该理解。诸如此类,预定义类型,如 integer,byte,single,double等通通如此

特别一些的是 string,class,array (还有更多);这些内容的复制并非无法实现,最简单的是 a =b  即复制了一个新的,但私有部分的内容是隐蔽的,编译器从根本上不提供这项功能
如果还是需要复制副本的功能,就可以用copymemory的方法实现了,知道了这个表长度直接复制即可

我做了一个最简单的: 复制对象
           演示代码: http://files.cnblogs.com/pctgl/copy2new.rar

                内有详细注释, 很简单

提示: 以上代码仅做演示一途, 绝非万全之策, 切不可用于正式项目,但也算较为安全,不会轻易弄挂你的程序


以后就是这帖的看客了, 各位有想多研究这方面的,不如来我的blog一起研究 pctgl.cnblogs.com

#37


话题可能越扯越远了,但真心觉得这问题和编绎器扯不上关系!

操作系统关心窗口,进程,线程等等对象,因此从操作系统的角度说,窗口,进程等对象所占内存是可精确计算的,因为操作系统了解它们的结构;但要知道一个用户自定义对象所占内存,操作系统恐怕就无能为力了,因为这些对象并不是直接向操作系统申请,而是由进程等对象代申请,操作系统的帐本上记的是进程的名字,而不是用户自定义对象的名字--当然,如果操作系统愿意为每一个申请内存的对象建帐本就另说!

延伸一点说,进程是否又愿意为进程内的每一个对象建个帐本呢?

从数学的角度说, 如果你要了解更详细的收支情况,那你就得有更详细的明细记录表.

为什么要和继承扯上关系统呢?继承是针对类来说的,而不是对象。我们说某类继承自某类,而不是说某对象继承自某对象。

关于复制副本,那要看你怎样理解“副本”这个东西了,B与A的指针成员都指向同一个地方,我们可认为B是A的副本,但从另一个角度说,B与A的指针成员虽然没指向同一个地方,但它们指向的地方的数据都是完全相同的,难道不认为B也是A的副本吗?就像a=1,b=a,虽然a,b地址不一样,但a,b的数据却是一样的。

copymemory只能得到第一种副本,并且算不上真正的副本,修改一下A的指针成员指向的数据,再看看B就知道了。在同一进程内还好,如果copymemory跨进程、跨机器的对象,恐怕可能出现的就是“该内存为XXX”了

关于a=b复制对象,如果知道“重载运算符”就容易多了,可惜,VB6这东西没有“重载”。。。

扯远了,钓鱼岛都这么紧张了,还。。。楼主咋不结贴?虽有不同看法,不过对你的问题意见还是一致的。

#38


如何获取对象变量所占字节数?【100分】好吧,结扎!

#39


看过代码吗,看懂了吗